C++: Use mkElement/unresolveElement consistently

This commit is contained in:
Ian Lynagh
2018-08-03 14:02:17 +01:00
parent 34c9892f77
commit a1e44041ec
90 changed files with 717 additions and 687 deletions

View File

@@ -56,12 +56,12 @@ class SuppressionComment extends CppStyleComment {
*/ */
class SuppressionScope extends @comment { class SuppressionScope extends @comment {
SuppressionScope() { SuppressionScope() {
this instanceof SuppressionComment mkElement(this) instanceof SuppressionComment
} }
/** Gets a suppression comment with this scope. */ /** Gets a suppression comment with this scope. */
SuppressionComment getSuppressionComment() { SuppressionComment getSuppressionComment() {
result = this result = mkElement(this)
} }
/** /**
@@ -72,7 +72,7 @@ class SuppressionScope extends @comment {
* [LGTM locations](https://lgtm.com/help/ql/locations). * [LGTM locations](https://lgtm.com/help/ql/locations).
*/ */
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) { predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
this.(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn) mkElement(this).(SuppressionComment).covers(filepath, startline, startcolumn, endline, endcolumn)
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */

View File

@@ -13,7 +13,7 @@ import cpp
string kindstr(Class c) string kindstr(Class c)
{ {
exists(int kind | usertypes(c, _, kind) | exists(int kind | usertypes(unresolveElement(c), _, kind) |
(kind = 1 and result = "Struct") or (kind = 1 and result = "Struct") or
(kind = 2 and result = "Class") or (kind = 2 and result = "Class") or
(kind = 6 and result = "Template class") (kind = 6 and result = "Template class")
@@ -48,21 +48,22 @@ predicate masterVde(VariableDeclarationEntry master, VariableDeclarationEntry vd
class VariableDeclarationGroup extends @var_decl { class VariableDeclarationGroup extends @var_decl {
VariableDeclarationGroup() { VariableDeclarationGroup() {
not previousVde(_, this) not previousVde(_, mkElement(this))
} }
Class getClass() { Class getClass() {
vdeInfo(this, result, _, _) vdeInfo(mkElement(this), result, _, _)
} }
// pragma[noopt] since otherwise the two locationInfo relations get join-ordered // pragma[noopt] since otherwise the two locationInfo relations get join-ordered
// after each other // after each other
pragma[noopt] pragma[noopt]
predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) { predicate hasLocationInfo(string path, int startline, int startcol, int endline, int endcol) {
exists(VariableDeclarationEntry last, Location lstart, Location lend | exists(Element thisElement, VariableDeclarationEntry last, Location lstart, Location lend |
masterVde(this, last) and thisElement = mkElement(this) and
masterVde(thisElement, last) and
this instanceof VariableDeclarationGroup and this instanceof VariableDeclarationGroup and
not previousVde(last, _) and not previousVde(last, _) and
exists(VariableDeclarationEntry vde | vde=this and vde instanceof VariableDeclarationEntry and vde.getLocation() = lstart) and exists(VariableDeclarationEntry vde | vde=mkElement(this) and vde instanceof VariableDeclarationEntry and vde.getLocation() = lstart) and
last.getLocation() = lend and last.getLocation() = lend and
lstart.hasLocationInfo(path, startline, startcol, _, _) and lstart.hasLocationInfo(path, startline, startcol, _, _) and
lend.hasLocationInfo(path, _, _, endline, endcol) lend.hasLocationInfo(path, _, _, endline, endcol)
@@ -70,15 +71,15 @@ class VariableDeclarationGroup extends @var_decl {
} }
string toString() { string toString() {
if previousVde(this, _) then if previousVde(mkElement(this), _) then
result = "group of " result = "group of "
+ strictcount(string name + strictcount(string name
| exists(VariableDeclarationEntry vde | exists(VariableDeclarationEntry vde
| masterVde(this, vde) and | masterVde(mkElement(this), vde) and
name = vde.getName())) name = vde.getName()))
+ " fields here" + " fields here"
else else
result = "declaration of " + this.(VariableDeclarationEntry).getVariable().getName() result = "declaration of " + mkElement(this).(VariableDeclarationEntry).getVariable().getName()
} }
} }

View File

@@ -3,12 +3,9 @@ import CPython.ArgParse
/* Root class of all 'C' objects */ /* Root class of all 'C' objects */
abstract class CObject extends @element { abstract class CObject extends Element {
abstract string getTrapID(); abstract string getTrapID();
/** Gets a textual representation of this element. */
abstract string toString();
} }

View File

@@ -98,7 +98,7 @@ predicate flowsToDefImpl(
or or
// `x++` // `x++`
exists (CrementOperation crem exists (CrementOperation crem
| def = crem and | mkElement(def) = crem and
crem.getOperand() = v.getAnAccess() and crem.getOperand() = v.getAnAccess() and
flowsToExpr(source, crem.getOperand(), pathMightOverflow)) flowsToExpr(source, crem.getOperand(), pathMightOverflow))
or or

View File

@@ -66,7 +66,7 @@ class Library extends LibraryT {
result = lib.getAFile() result = lib.getAFile()
) or exists(@external_package ep | ) or exists(@external_package ep |
this = LibraryTExternalPackage(ep, _, _) and this = LibraryTExternalPackage(ep, _, _) and
header_to_external_package(result, ep) header_to_external_package(unresolveElement(result), ep)
) )
} }
} }

View File

@@ -12,6 +12,6 @@
import cpp import cpp
from File f, int comments, int total from File f, int comments, int total
where f.fromSource() and numlines(f, total, _, comments) and total > 0 where f.fromSource() and numlines(unresolveElement(f), total, _, comments) and total > 0
select f, 100.0 * (comments.(float) / total.(float)) as ratio select f, 100.0 * (comments.(float) / total.(float)) as ratio
order by ratio desc order by ratio desc

View File

@@ -7,6 +7,6 @@
import semmle.code.cpp.pointsto.PointsTo import semmle.code.cpp.pointsto.PointsTo
select count(int set, Element location | setlocations(set, location)), select count(int set, Element location | setlocations(set, unresolveElement(location))),
count(int set, Element element | pointstosets(set, element)) count(int set, Element element | pointstosets(set, unresolveElement(element)))

View File

@@ -27,7 +27,7 @@ predicate tryLockCondition(VariableAccess access,
(cond = call.getParent*() and (cond = call.getParent*() and
cond.isCondition() and cond.isCondition() and
failNode = cond.getASuccessor() and failNode = cond.getASuccessor() and
failNode instanceof BasicBlockWithReturn)) unresolveElement(failNode) instanceof BasicBlockWithReturn))
} }
/** /**

View File

@@ -29,7 +29,7 @@ predicate failedLock(MutexType t, BasicBlock lockblock, BasicBlock failblock) {
exists (ControlFlowNode lock | exists (ControlFlowNode lock |
lock = lockblock.getEnd() and lock = lockblock.getEnd() and
lock = t.getLockAccess() and lock = t.getLockAccess() and
lock.getAFalseSuccessor() = failblock lock.getAFalseSuccessor() = mkElement(failblock)
) )
} }

View File

@@ -91,7 +91,7 @@ class SimilarBlock extends Copy, @similarity
FunctionDeclarationEntry sourceMethod() { FunctionDeclarationEntry sourceMethod() {
result.isDefinition() and result.isDefinition() and
exists(result.getLocation()) and numlines(result.getFunction(),_,_,_) exists(result.getLocation()) and numlines(unresolveElement(result.getFunction()),_,_,_)
} }
int numberOfSourceMethods(Class c) { int numberOfSourceMethods(Class c) {

View File

@@ -24,7 +24,7 @@ class Commit extends @svnentry {
string getMessage() { svnentrymsg(this, result) } string getMessage() { svnentrymsg(this, result) }
string getAnAffectedFilePath(string action) { string getAnAffectedFilePath(string action) {
exists(File rawFile | svnaffectedfiles(this, rawFile, action) | exists(File rawFile | svnaffectedfiles(this, unresolveElement(rawFile), action) |
result = rawFile.getAbsolutePath() result = rawFile.getAbsolutePath()
) )
} }
@@ -34,7 +34,7 @@ class Commit extends @svnentry {
File getAnAffectedFile(string action) { File getAnAffectedFile(string action) {
// Workaround for incorrect keys in SVN data // Workaround for incorrect keys in SVN data
exists(File svnFile | svnFile.getAbsolutePath() = result.getAbsolutePath() | exists(File svnFile | svnFile.getAbsolutePath() = result.getAbsolutePath() |
svnaffectedfiles(this,svnFile,action) svnaffectedfiles(this,unresolveElement(svnFile),action)
) )
and exists(result.getMetrics().getNumberOfLinesOfCode()) and exists(result.getMetrics().getNumberOfLinesOfCode())
} }
@@ -44,7 +44,7 @@ class Commit extends @svnentry {
private predicate churnForFile(File f, int added, int deleted) { private predicate churnForFile(File f, int added, int deleted) {
// Workaround for incorrect keys in SVN data // Workaround for incorrect keys in SVN data
exists(File svnFile | svnFile.getAbsolutePath() = f.getAbsolutePath() | exists(File svnFile | svnFile.getAbsolutePath() = f.getAbsolutePath() |
svnchurn(this,svnFile,added,deleted) svnchurn(this,unresolveElement(svnFile),added,deleted)
) )
and exists(f.getMetrics().getNumberOfLinesOfCode()) and exists(f.getMetrics().getNumberOfLinesOfCode())
} }

View File

@@ -19,9 +19,9 @@ An approximation of this definition is classes with pure virtual functions and l
*/ */
class InterfaceClass extends Class { class InterfaceClass extends Class {
InterfaceClass() { InterfaceClass() {
exists(MemberFunction m | m.getDeclaringType() = this and not compgenerated(m)) exists(MemberFunction m | m.getDeclaringType() = this and not compgenerated(unresolveElement(m)))
and and
forall(MemberFunction m | m.getDeclaringType() = this and not compgenerated(m) | m instanceof PureVirtualFunction) forall(MemberFunction m | m.getDeclaringType() = this and not compgenerated(unresolveElement(m)) | m instanceof PureVirtualFunction)
and and
count(MemberVariable v | v.getDeclaringType() = this) < 3 count(MemberVariable v | v.getDeclaringType() = this) < 3
} }

View File

@@ -80,8 +80,8 @@ where impureExprInDisallowedContext(e) and
not e.isCompilerGenerated() and not e.isCompilerGenerated() and
// A few cases that are always ok // A few cases that are always ok
not e instanceof Conversion and not e instanceof Conversion and
not exists(@ctorinit ci | e = ci) and not exists(@ctorinit ci | e = mkElement(ci)) and
not exists(@dtordestruct dd | e = dd) and not exists(@dtordestruct dd | e = mkElement(dd)) and
// Avoid flagging nested expressions // Avoid flagging nested expressions
not impureExprInDisallowedContext(e.getParent+()) not impureExprInDisallowedContext(e.getParent+())
select e.findRootCause(), "AV Rule 204: A single operation with side-effects shall only be used in certain contexts." select e.findRootCause(), "AV Rule 204: A single operation with side-effects shall only be used in certain contexts."

View File

@@ -35,7 +35,7 @@ class AutogeneratedFile extends File {
cached AutogeneratedFile() { cached AutogeneratedFile() {
exists(int limit, int head | exists(int limit, int head |
head <= 5 and head <= 5 and
limit = max(int line | locations_default(_, this, head, _, line, _)) + 5 limit = max(int line | locations_default(_, unresolveElement(this), head, _, line, _)) + 5
| |
exists (Comment c | c.getFile() = this and c.getLocation().getStartLine() <= limit and isAutogeneratedComment(c)) exists (Comment c | c.getFile() = this and c.getLocation().getStartLine() <= limit and isAutogeneratedComment(c))
) )

View File

@@ -12,7 +12,7 @@ private import semmle.code.cpp.internal.Type
*/ */
class Class extends UserType { class Class extends UserType {
Class() { Class() {
isClass(this) and this = resolve(_) isClass(unresolveElement(this))
} }
/** Gets a child declaration of this class. */ /** Gets a child declaration of this class. */
@@ -75,7 +75,7 @@ class Class extends UserType {
* If you also want template instantiations of results, see * If you also want template instantiations of results, see
* `getAMember(int)`. * `getAMember(int)`.
*/ */
Declaration getCanonicalMember(int index) { member(this,index,result) } Declaration getCanonicalMember(int index) { member(unresolveElement(this),index,unresolveElement(result)) }
/** /**
* Gets the (zero-based) `index`th canonical member declared in this * Gets the (zero-based) `index`th canonical member declared in this
@@ -94,7 +94,7 @@ class Class extends UserType {
* DEPRECATED: Use `getCanonicalMember(int)` or `getAMember(int)` instead. * DEPRECATED: Use `getCanonicalMember(int)` or `getAMember(int)` instead.
* Gets the `index`th member of this class. * Gets the `index`th member of this class.
*/ */
deprecated Declaration getMember(int index) { member(this,index,result) } deprecated Declaration getMember(int index) { member(unresolveElement(this),index,unresolveElement(result)) }
/** /**
* DEPRECATED: As this includes a somewhat arbitrary number of * DEPRECATED: As this includes a somewhat arbitrary number of
@@ -416,7 +416,7 @@ class Class extends UserType {
* compiled for. For this reason, the `is_pod_class` predicate is * compiled for. For this reason, the `is_pod_class` predicate is
* generated by the extractor. * generated by the extractor.
*/ */
predicate isPOD() { is_pod_class(this) } predicate isPOD() { is_pod_class(unresolveElement(this)) }
/** /**
* Holds if this class is abstract, in other words whether it declares one * Holds if this class is abstract, in other words whether it declares one
@@ -513,7 +513,7 @@ class Class extends UserType {
* classes. * classes.
*/ */
int getVirtualBaseClassByteOffset(Class base) { int getVirtualBaseClassByteOffset(Class base) {
virtual_base_offsets(this, base, result) virtual_base_offsets(unresolveElement(this), unresolveElement(base), result)
} }
/** /**
@@ -566,7 +566,7 @@ class Class extends UserType {
* The alignment of this type in bytes (on the machine where facts were * The alignment of this type in bytes (on the machine where facts were
* extracted). * extracted).
*/ */
int getAlignment() { usertypesize(this,_,result) } int getAlignment() { usertypesize(unresolveElement(this),_,result) }
/** /**
* Holds if this class is constructed from another class as a result of * Holds if this class is constructed from another class as a result of
@@ -574,7 +574,7 @@ class Class extends UserType {
* from a class nested in a class template. * from a class nested in a class template.
*/ */
predicate isConstructedFrom(Class c) { predicate isConstructedFrom(Class c) {
class_instantiation(this, c) class_instantiation(unresolveElement(this), unresolveElement(c))
} }
/** /**
@@ -597,7 +597,7 @@ class Class extends UserType {
* `i`th template parameter. * `i`th template parameter.
*/ */
Type getTemplateArgument(int i) { Type getTemplateArgument(int i) {
class_template_argument(this,i,unresolve(result)) class_template_argument(unresolveElement(this),i,unresolveElement(result))
} }
/** /**
@@ -614,7 +614,7 @@ class Class extends UserType {
/** Holds if this class was declared 'final'. */ /** Holds if this class was declared 'final'. */
predicate isFinal() { predicate isFinal() {
usertype_final(this) usertype_final(unresolveElement(this))
} }
/** Gets a link target which references this class. */ /** Gets a link target which references this class. */
@@ -631,7 +631,7 @@ class Class extends UserType {
* using lowercase letters (e.g. "01234567-89ab-cdef-0123-456789abcdef"). * using lowercase letters (e.g. "01234567-89ab-cdef-0123-456789abcdef").
*/ */
string getUuid() { string getUuid() {
usertype_uuid(this, result) usertype_uuid(unresolveElement(this), result)
} }
private Type getAFieldSubobjectType() { private Type getAFieldSubobjectType() {
@@ -741,7 +741,7 @@ class Class extends UserType {
* A class derivation, for example the "public B" in * A class derivation, for example the "public B" in
* "class D : public B { ... };". * "class D : public B { ... };".
*/ */
class ClassDerivation extends Locatable, @derivation { class ClassDerivation extends Locatable, @derivation {
/** /**
* Gets the class/struct from which we are actually deriving, resolving a * Gets the class/struct from which we are actually deriving, resolving a
* typedef if necessary. For example, the base class in the following * typedef if necessary. For example, the base class in the following
@@ -764,7 +764,7 @@ class ClassDerivation extends Locatable, @derivation {
* struct D : T {}; * struct D : T {};
*/ */
Type getBaseType() { Type getBaseType() {
derivations(this,_,_,unresolve(result),_) derivations(unresolveElement(this),_,_,unresolveElement(result),_)
} }
/** /**
@@ -775,7 +775,7 @@ class ClassDerivation extends Locatable, @derivation {
* struct D : B {}; * struct D : B {};
*/ */
Class getDerivedClass() { Class getDerivedClass() {
derivations(this,unresolve(result),_,_,_) derivations(unresolveElement(this),unresolveElement(result),_,_,_)
} }
/** /**
@@ -784,12 +784,12 @@ class ClassDerivation extends Locatable, @derivation {
* derivation of B2 in "struct D : B1, B2 { ... };" would be 1. * derivation of B2 in "struct D : B1, B2 { ... };" would be 1.
*/ */
int getIndex() { int getIndex() {
derivations(this,_,result,_,_) derivations(unresolveElement(this),_,result,_,_)
} }
/** Gets a specifier (for example "public") applied to the derivation. */ /** Gets a specifier (for example "public") applied to the derivation. */
Specifier getASpecifier() { Specifier getASpecifier() {
derspecifiers(this,result) derspecifiers(unresolveElement(this),unresolveElement(result))
} }
/** Holds if the derivation has specifier `s`. */ /** Holds if the derivation has specifier `s`. */
@@ -804,7 +804,7 @@ class ClassDerivation extends Locatable, @derivation {
/** Gets the location of the derivation. */ /** Gets the location of the derivation. */
override Location getLocation() { override Location getLocation() {
derivations(this,_,_,_,result) derivations(unresolveElement(this),_,_,_,result)
} }
/** /**
@@ -816,7 +816,7 @@ class ClassDerivation extends Locatable, @derivation {
* classes. * classes.
*/ */
int getByteOffset() { int getByteOffset() {
direct_base_offsets(this, result) direct_base_offsets(unresolveElement(this), result)
} }
override string toString() { override string toString() {
@@ -869,7 +869,7 @@ class AbstractClass extends Class {
* of class templates). * of class templates).
*/ */
class TemplateClass extends Class { class TemplateClass extends Class {
TemplateClass() { usertypes(this,_,6) } TemplateClass() { usertypes(unresolveElement(this),_,6) }
Class getAnInstantiation() { Class getAnInstantiation() {
result.isConstructedFrom(this) and result.isConstructedFrom(this) and
exists(result.getATemplateArgument()) exists(result.getATemplateArgument())
@@ -955,7 +955,7 @@ class PartialClassTemplateSpecialization extends ClassTemplateSpecialization {
*/ */
class Interface extends Class { class Interface extends Class {
Interface() { Interface() {
forex(Declaration m | m.getDeclaringType() = this.getABaseClass*() and not compgenerated(m) | m instanceof PureVirtualFunction) forex(Declaration m | m.getDeclaringType() = this.getABaseClass*() and not compgenerated(unresolveElement(m)) | m instanceof PureVirtualFunction)
} }
} }
@@ -998,7 +998,7 @@ class VirtualBaseClass extends Class {
*/ */
class ProxyClass extends UserType { class ProxyClass extends UserType {
ProxyClass() { ProxyClass() {
usertypes(this,_,9) usertypes(unresolveElement(this),_,9)
} }
/** Gets the location of the proxy class. */ /** Gets the location of the proxy class. */
@@ -1008,7 +1008,7 @@ class ProxyClass extends UserType {
/** 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() {
is_proxy_class_for(this,result) is_proxy_class_for(unresolveElement(this),unresolveElement(result))
} }
} }

View File

@@ -6,9 +6,9 @@ import semmle.code.cpp.Element
*/ */
class Comment extends Locatable, @comment { class Comment extends Locatable, @comment {
override string toString() { result = this.getContents() } override string toString() { result = this.getContents() }
override Location getLocation() { comments(this,_,result) } override Location getLocation() { comments(unresolveElement(this),_,result) }
string getContents() { comments(this,result,_) } string getContents() { comments(unresolveElement(this),result,_) }
Element getCommentedElement() { commentbinding(this,result) } Element getCommentedElement() { commentbinding(unresolveElement(this),unresolveElement(result)) }
} }
/** /**

View File

@@ -37,7 +37,7 @@ class Compilation extends @compilation {
/** Gets a file compiled during this invocation. */ /** Gets a file compiled during this invocation. */
File getAFileCompiled() { result = getFileCompiled(_) } File getAFileCompiled() { result = getFileCompiled(_) }
File getFileCompiled(int i) { File getFileCompiled(int i) {
compilation_compiling_files(this, i, result) compilation_compiling_files(this, i, unresolveElement(result))
} }
/** /**

View File

@@ -309,7 +309,7 @@ abstract class AccessHolder extends Declaration {
isDirectPublicBaseOf*(base, derived) isDirectPublicBaseOf*(base, derived)
or or
exists(DirectAccessHolder n | exists(DirectAccessHolder n |
this.getEnclosingAccessHolder*() = n and this.getEnclosingAccessHolder*() = mkElement(n) and
// Derivations using (4.2) or (4.3) at least once. // Derivations using (4.2) or (4.3) at least once.
n.thisCanAccessClassTrans(base, derived) n.thisCanAccessClassTrans(base, derived)
) )
@@ -379,7 +379,7 @@ abstract class AccessHolder extends Declaration {
everyoneCouldAccessMember(memberClass, memberAccess, derived) everyoneCouldAccessMember(memberClass, memberAccess, derived)
or or
exists(DirectAccessHolder n | exists(DirectAccessHolder n |
this.getEnclosingAccessHolder*() = n and this.getEnclosingAccessHolder*() = mkElement(n) and
// Any other derivation. // Any other derivation.
n.thisCouldAccessMember(memberClass, memberAccess, derived) n.thisCouldAccessMember(memberClass, memberAccess, derived)
) )
@@ -398,9 +398,9 @@ abstract class AccessHolder extends Declaration {
*/ */
private class DirectAccessHolder extends @declaration { private class DirectAccessHolder extends @declaration {
DirectAccessHolder() { DirectAccessHolder() {
this instanceof Class mkElement(this) instanceof Class
or or
exists(FriendDecl fd | fd.getFriend() = this) exists(FriendDecl fd | fd.getFriend() = mkElement(this))
} }
/** /**
@@ -486,7 +486,7 @@ private class DirectAccessHolder extends @declaration {
) )
or or
// Rule (5.4) followed by Rule (5.2) // Rule (5.4) followed by Rule (5.2)
exists(Class between | this.(AccessHolder).canAccessClass(between, derived) | exists(Class between | mkElement(this).(AccessHolder).canAccessClass(between, derived) |
between.accessOfBaseMember(memberClass, memberAccess) between.accessOfBaseMember(memberClass, memberAccess)
.hasName("private") and .hasName("private") and
this.isFriendOfOrEqualTo(between) this.isFriendOfOrEqualTo(between)
@@ -539,12 +539,12 @@ private class DirectAccessHolder extends @declaration {
} }
private predicate isFriendOfOrEqualTo(Class c) { private predicate isFriendOfOrEqualTo(Class c) {
exists(FriendDecl fd | fd.getDeclaringClass() = c | this = fd.getFriend()) exists(FriendDecl fd | fd.getDeclaringClass() = c | mkElement(this) = fd.getFriend())
or or
this = c mkElement(this) = c
} }
string toString() { result = this.(Declaration).toString() } string toString() { result = mkElement(this).(Declaration).toString() }
} }
/** /**

View File

@@ -7,26 +7,26 @@ class Diagnostic extends Locatable, @diagnostic {
* Gets the severity of the message, on a range from 1 to 5: 1=remark, * Gets the severity of the message, on a range from 1 to 5: 1=remark,
* 2=warning, 3=discretionary error, 4=error, 5=catastrophic error. * 2=warning, 3=discretionary error, 4=error, 5=catastrophic error.
*/ */
int getSeverity() { diagnostics(this, result, _, _, _, _) } int getSeverity() { diagnostics(unresolveElement(this), result, _, _, _, _) }
/** Gets the error code for this compiler message. */ /** Gets the error code for this compiler message. */
string getTag() { diagnostics(this, _, result, _, _, _) } string getTag() { diagnostics(unresolveElement(this), _, result, _, _, _) }
predicate hasTag(string s) { this.getTag() = s } predicate hasTag(string s) { this.getTag() = s }
/** /**
* Gets the error message text associated with this compiler * Gets the error message text associated with this compiler
* diagnostic. * diagnostic.
*/ */
string getMessage() { diagnostics(this, _, _, result, _, _) } string getMessage() { diagnostics(unresolveElement(this), _, _, result, _, _) }
/** /**
* Gets the full error message text associated with this compiler * Gets the full error message text associated with this compiler
* diagnostic. * diagnostic.
*/ */
string getFullMessage() { diagnostics(this, _, _, _, result, _) } string getFullMessage() { diagnostics(unresolveElement(this), _, _, _, result, _) }
/** Gets the source location corresponding to the compiler message. */ /** Gets the source location corresponding to the compiler message. */
override Location getLocation() { diagnostics(this, _, _, _, _, result) } override Location getLocation() { diagnostics(unresolveElement(this), _, _, _, _, result) }
override string toString() { result = this.getMessage() } override string toString() { result = this.getMessage() }

View File

@@ -2,13 +2,27 @@ import semmle.code.cpp.Location
private import semmle.code.cpp.Enclosing private import semmle.code.cpp.Enclosing
private import semmle.code.cpp.internal.Type private import semmle.code.cpp.internal.Type
cached @element resolveElement(@element e) {
if isClass(e)
then result = resolve(e)
else result = e
}
cached Element mkElement(@element e) {
result = resolveElement(e)
}
cached @element unresolveElement(Element e) {
resolveElement(result) = e
}
/** /**
* A C/C++ element. This class is the base class for all C/C++ * A C/C++ element. This class is the base class for all C/C++
* elements, such as functions, classes, expressions, and so on. * elements, such as functions, classes, expressions, and so on.
*/ */
class Element extends @element { class Element extends @element {
Element() { Element() {
isElement(this) this = resolveElement(_)
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
@@ -111,7 +125,7 @@ class Element extends @element {
// result instanceof block|function // result instanceof block|function
or or
exists (Block b exists (Block b
| this = b and blockscope(b, result)) | this = b and blockscope(unresolveElement(b), unresolveElement(result)))
or or
exists (TemplateFunction tf exists (TemplateFunction tf
| this = tf.getATemplateArgument() and result = tf) | this = tf.getATemplateArgument() and result = tf)
@@ -122,7 +136,7 @@ class Element extends @element {
| this = s and result = s.getParent()) | this = s and result = s.getParent())
or or
using_container(result, this) using_container(unresolveElement(result), unresolveElement(this))
} }
/** /**
@@ -144,17 +158,17 @@ class Element extends @element {
} }
private Element getEnclosingElementPref() { private Element getEnclosingElementPref() {
enclosingfunction(this, result) or enclosingfunction(unresolveElement(this), unresolveElement(result)) or
result.(Function) = stmtEnclosingElement(this) or result.(Function) = stmtEnclosingElement(this) or
this.(LocalScopeVariable).getFunction() = result or this.(LocalScopeVariable).getFunction() = result or
enumconstants(this, result, _, _, _, _) or enumconstants(unresolveElement(this), unresolveElement(result), _, _, _, _) or
derivations(this, result, _, _, _) or derivations(unresolveElement(this), unresolveElement(result), _, _, _) or
stmtparents(this, _, result) or stmtparents(unresolveElement(this), _, unresolveElement(result)) or
exprparents(this, _, result) or exprparents(unresolveElement(this), _, unresolveElement(result)) or
namequalifiers(this, result, _, _) or namequalifiers(unresolveElement(this), unresolveElement(result), _, _) or
initialisers(this, result, _, _) or initialisers(unresolveElement(this), unresolveElement(result), _, _) or
exprconv(result, this) or exprconv(unresolveElement(result), unresolveElement(this)) or
param_decl_bind(this,_,result) param_decl_bind(unresolveElement(this),_,unresolveElement(result))
} }
/** Gets the closest `Element` enclosing this one. */ /** Gets the closest `Element` enclosing this one. */
@@ -167,7 +181,7 @@ class Element extends @element {
or or
result = exprEnclosingElement(this) result = exprEnclosingElement(this)
or or
var_decls(this, result, _, _, _) var_decls(unresolveElement(this), unresolveElement(result), _, _, _)
) )
) )
} }
@@ -216,13 +230,13 @@ private predicate isFromTemplateInstantiationRec(Element e, Element instantiatio
} }
private predicate isFromUninstantiatedTemplateRec(Element e, Element template) { private predicate isFromUninstantiatedTemplateRec(Element e, Element template) {
is_class_template(template) and is_class_template(unresolveElement(template)) and
e = template e = template
or or
is_function_template(template) and is_function_template(unresolveElement(template)) and
e = template e = template
or or
is_variable_template(template) and is_variable_template(unresolveElement(template)) and
e = template e = template
or or
isFromUninstantiatedTemplateRec(e.getEnclosingElement(), template) isFromUninstantiatedTemplateRec(e.getEnclosingElement(), template)
@@ -233,7 +247,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(..., \"" + getMessage() + "\")" }
Expr getCondition() { static_asserts(this, result, _, _) } Expr getCondition() { static_asserts(unresolveElement(this), unresolveElement(result), _, _) }
string getMessage() { static_asserts(this, _, result, _) } string getMessage() { static_asserts(unresolveElement(this), _, result, _) }
override Location getLocation() { static_asserts(this, _, _, result) } override Location getLocation() { static_asserts(unresolveElement(this), _, _, result) }
} }

View File

@@ -23,10 +23,10 @@ cached Element exprEnclosingElement(Expr e) {
else if i.getDeclaration() instanceof Parameter else if i.getDeclaration() instanceof Parameter
then result = i.getDeclaration().(Parameter).getFunction() then result = i.getDeclaration().(Parameter).getFunction()
else result = i.getDeclaration()) or else result = i.getDeclaration()) or
exists(Expr anc | expr_ancestor(e, anc) and result = exprEnclosingElement(anc)) or exists(Expr anc | expr_ancestor(unresolveElement(e), unresolveElement(anc)) and result = exprEnclosingElement(anc)) or
exists(Stmt anc | expr_ancestor(e, anc) and result = stmtEnclosingElement(anc)) or exists(Stmt anc | expr_ancestor(unresolveElement(e), unresolveElement(anc)) and result = stmtEnclosingElement(anc)) or
exists(DeclarationEntry de | exists(DeclarationEntry de |
expr_ancestor(e, de) and expr_ancestor(unresolveElement(e), unresolveElement(de)) and
if exists(DeclStmt ds | de = ds.getADeclarationEntry()) if exists(DeclStmt ds | de = ds.getADeclarationEntry())
then exists(DeclStmt ds | then exists(DeclStmt ds |
de = ds.getADeclarationEntry() and de = ds.getADeclarationEntry() and

View File

@@ -7,7 +7,7 @@ private import semmle.code.cpp.internal.Type
class Enum extends UserType, IntegralOrEnumType { class Enum extends UserType, IntegralOrEnumType {
/** Gets an enumerator of this enumeration. */ /** Gets an enumerator of this enumeration. */
EnumConstant getAnEnumConstant() { result.getDeclaringEnum() = this } EnumConstant getAnEnumConstant() { result.getDeclaringEnum() = this }
EnumConstant getEnumConstant(int index) { enumconstants(result,this,index,_,_,_) } EnumConstant getEnumConstant(int index) { enumconstants(unresolveElement(result),unresolveElement(this),index,_,_,_) }
/** /**
* Gets a descriptive string for the enum. This method is only intended to * Gets a descriptive string for the enum. This method is only intended to
@@ -24,7 +24,7 @@ class Enum extends UserType, IntegralOrEnumType {
* For example: `enum E : int`. * For example: `enum E : int`.
*/ */
predicate hasExplicitUnderlyingType() { predicate hasExplicitUnderlyingType() {
derivations(_, this, _, _, _) derivations(_, unresolveElement(this), _, _, _)
} }
/** /**
@@ -32,7 +32,7 @@ class Enum extends UserType, IntegralOrEnumType {
* For example: `int` in `enum E : int`. * For example: `int` in `enum E : int`.
*/ */
Type getExplicitUnderlyingType() { Type getExplicitUnderlyingType() {
derivations(_, this, _, result, _) derivations(_, unresolveElement(this), _, unresolveElement(result), _)
} }
} }
@@ -72,7 +72,7 @@ class NestedEnum extends Enum {
*/ */
class ScopedEnum extends Enum { class ScopedEnum extends Enum {
ScopedEnum() { ScopedEnum() {
usertypes(this,_,13) usertypes(unresolveElement(this),_,13)
} }
} }
@@ -83,11 +83,11 @@ class ScopedEnum extends Enum {
* *
* Enumerators are also knowns as enumeration constants. * Enumerators are also knowns as enumeration constants.
*/ */
class EnumConstant extends @enumconstant, Declaration { class EnumConstant extends Declaration, @enumconstant {
/** /**
* Gets the enumeration of which this enumerator is a member. * Gets the enumeration of which this enumerator is a member.
*/ */
Enum getDeclaringEnum() { enumconstants(this,result,_,_,_,_) } Enum getDeclaringEnum() { enumconstants(unresolveElement(this),unresolveElement(result),_,_,_,_) }
override Class getDeclaringType() { override Class getDeclaringType() {
result = this.getDeclaringEnum().getDeclaringType() result = this.getDeclaringEnum().getDeclaringType()
@@ -96,7 +96,7 @@ class EnumConstant extends @enumconstant, Declaration {
/** /**
* Gets the name of this enumerator. * Gets the name of this enumerator.
*/ */
override string getName() { enumconstants(this,_,_,_,result,_) } override string getName() { enumconstants(unresolveElement(this),_,_,_,result,_) }
/** /**
* Gets the value that this enumerator is initialized to, as a * Gets the value that this enumerator is initialized to, as a
@@ -106,13 +106,13 @@ class EnumConstant extends @enumconstant, Declaration {
string getValue() { result = this.getInitializer().getExpr().getValue() } string getValue() { result = this.getInitializer().getExpr().getValue() }
/** Gets the type of this enumerator. */ /** Gets the type of this enumerator. */
Type getType() { enumconstants(this,_,_,unresolve(result),_,_) } Type getType() { enumconstants(unresolveElement(this),_,_,unresolveElement(result),_,_) }
/** Gets the location of a declaration of this enumerator. */ /** Gets the location of a declaration of this enumerator. */
override Location getADeclarationLocation() { result = this.getDefinitionLocation() } override Location getADeclarationLocation() { result = this.getDefinitionLocation() }
/** Gets the location of the definition of this enumerator. */ /** Gets the location of the definition of this enumerator. */
override Location getDefinitionLocation() { enumconstants(this,_,_,_,_,result) } override Location getDefinitionLocation() { enumconstants(unresolveElement(this),_,_,_,_,result) }
/** Gets the location of the definition of this enumerator. */ /** Gets the location of the definition of this enumerator. */
override Location getLocation() { result = this.getDefinitionLocation() } override Location getLocation() { result = this.getDefinitionLocation() }
@@ -124,7 +124,7 @@ class EnumConstant extends @enumconstant, Declaration {
EnumConstantAccess getAnAccess() { result.getTarget() = this } EnumConstantAccess getAnAccess() { result.getTarget() = this }
/** Gets a specifier of this enumerator. */ /** Gets a specifier of this enumerator. */
override Specifier getASpecifier() { varspecifiers(this,result) } override Specifier getASpecifier() { varspecifiers(unresolveElement(this),unresolveElement(result)) }
/** /**
* An attribute of this enumerator. * An attribute of this enumerator.
@@ -133,6 +133,6 @@ class EnumConstant extends @enumconstant, Declaration {
* which is only supported by Clang. * which is only supported by Clang.
*/ */
Attribute getAnAttribute() { Attribute getAnAttribute() {
varattributes(this, result) varattributes(unresolveElement(this), unresolveElement(result))
} }
} }

View File

@@ -8,14 +8,14 @@ import semmle.code.cpp.exprs.Access
class Field extends MemberVariable { class Field extends MemberVariable {
Field() { Field() {
fieldoffsets(this,_,_) fieldoffsets(unresolveElement(this),_,_)
} }
/** /**
* Gets the offset of this field in bytes from the start of its declaring * Gets the offset of this field in bytes from the start of its declaring
* type (on the machine where facts were extracted). * type (on the machine where facts were extracted).
*/ */
int getByteOffset() { fieldoffsets(this,result,_) } int getByteOffset() { fieldoffsets(unresolveElement(this),result,_) }
/** /**
* Gets the byte offset within `mostDerivedClass` of each occurence of this * Gets the byte offset within `mostDerivedClass` of each occurence of this
@@ -70,13 +70,13 @@ class Field extends MemberVariable {
* Syntactically, this looks like `int x : 3` in `struct S { int x : 3; };`. * Syntactically, this looks like `int x : 3` in `struct S { int x : 3; };`.
*/ */
class BitField extends Field { class BitField extends Field {
BitField() { bitfield(this,_,_) } BitField() { bitfield(unresolveElement(this),_,_) }
/** /**
* Gets the size of this bitfield in bits (on the machine where facts * Gets the size of this bitfield in bits (on the machine where facts
* were extracted). * were extracted).
*/ */
int getNumBits() { bitfield(this,result,_) } int getNumBits() { bitfield(unresolveElement(this),result,_) }
/** /**
* Gets the value which appeared after the colon in the bitfield * Gets the value which appeared after the colon in the bitfield
@@ -88,13 +88,13 @@ class BitField extends Field {
* `getNumBits` will give 32, whereas `getDeclaredNumBits` will give * `getNumBits` will give 32, whereas `getDeclaredNumBits` will give
* 1234. * 1234.
*/ */
int getDeclaredNumBits() { bitfield(this,_,result) } int getDeclaredNumBits() { bitfield(unresolveElement(this),_,result) }
/** /**
* Gets the offset of this bitfield in bits from the byte identified by * Gets the offset of this bitfield in bits from the byte identified by
* getByteOffset (on the machine where facts were extracted). * getByteOffset (on the machine where facts were extracted).
*/ */
int getBitOffset() { fieldoffsets(this,_,result) } int getBitOffset() { fieldoffsets(unresolveElement(this),_,result) }
predicate isAnonymous() { predicate isAnonymous() {
hasName("(unnamed bitfield)") hasName("(unnamed bitfield)")

View File

@@ -127,7 +127,7 @@ abstract class Container extends Locatable, @container {
/** 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() {
containerparent(result, this) containerparent(unresolveElement(result), unresolveElement(this))
} }
/** Gets a file or sub-folder in this container. */ /** Gets a file or sub-folder in this container. */
@@ -179,7 +179,7 @@ abstract class Container extends Locatable, @container {
*/ */
class Folder extends Container, @folder { class Folder extends Container, @folder {
override string getAbsolutePath() { override string getAbsolutePath() {
folders(this, result, _) folders(unresolveElement(this), result, _)
} }
override Location getLocation() { override Location getLocation() {
@@ -200,7 +200,7 @@ class Folder extends Container, @folder {
* Gets the name of this folder. * Gets the name of this folder.
*/ */
deprecated deprecated
string getName() { folders(this,result,_) } string getName() { folders(unresolveElement(this),result,_) }
/** /**
* DEPRECATED: use `getAbsolutePath` instead. * DEPRECATED: use `getAbsolutePath` instead.
@@ -223,7 +223,7 @@ class Folder extends Container, @folder {
deprecated deprecated
string getShortName() { string getShortName() {
exists (string longnameRaw, string longname exists (string longnameRaw, string longname
| folders(this,_,longnameRaw) and | folders(unresolveElement(this),_,longnameRaw) and
longname = longnameRaw.replaceAll("\\", "/") longname = longnameRaw.replaceAll("\\", "/")
| exists (int index | exists (int index
| result = longname.splitAt("/", index) and | result = longname.splitAt("/", index) and
@@ -235,7 +235,7 @@ class Folder extends Container, @folder {
* Gets the parent folder. * Gets the parent folder.
*/ */
deprecated deprecated
Folder getParent() { containerparent(result,this) } Folder getParent() { containerparent(unresolveElement(result),unresolveElement(this)) }
} }
/** /**
@@ -252,7 +252,7 @@ class Folder extends Container, @folder {
*/ */
class File extends Container, @file { class File extends Container, @file {
override string getAbsolutePath() { override string getAbsolutePath() {
files(this, result, _, _, _) files(unresolveElement(this), result, _, _, _)
} }
override string toString() { override string toString() {
@@ -274,12 +274,12 @@ class File extends Container, @file {
/** Holds if this file was compiled as C (at any point). */ /** Holds if this file was compiled as C (at any point). */
predicate compiledAsC() { predicate compiledAsC() {
fileannotations(this,1,"compiled as c","1") fileannotations(unresolveElement(this),1,"compiled as c","1")
} }
/** Holds if this file was compiled as C++ (at any point). */ /** Holds if this file was compiled as C++ (at any point). */
predicate compiledAsCpp() { predicate compiledAsCpp() {
fileannotations(this,1,"compiled as c++","1") fileannotations(unresolveElement(this),1,"compiled as c++","1")
} }
/** /**
@@ -333,14 +333,14 @@ class File extends Container, @file {
* Gets the folder which contains this file. * Gets the folder which contains this file.
*/ */
deprecated deprecated
Folder getParent() { containerparent(result,this) } Folder getParent() { containerparent(unresolveElement(result),unresolveElement(this)) }
/** /**
* Holds if this file may be from source. This predicate holds for all files * Holds if this file may be from source. This predicate holds for all files
* except the dummy file, whose name is the empty string, which contains * except the dummy file, whose name is the empty string, which contains
* declarations that are built into the compiler. * declarations that are built into the compiler.
*/ */
override predicate fromSource() { numlines(this,_,_,_) } override predicate fromSource() { numlines(unresolveElement(this),_,_,_) }
/** /**
* Holds if this file may be from a library. * Holds if this file may be from a library.
@@ -359,7 +359,7 @@ class File extends Container, @file {
* "/usr/home/me/myprogram.c". * "/usr/home/me/myprogram.c".
*/ */
deprecated deprecated
string getName() { files(this,result,_,_,_) } string getName() { files(unresolveElement(this),result,_,_,_) }
/** /**
* DEPRECATED: Use `getAbsolutePath` instead. * DEPRECATED: Use `getAbsolutePath` instead.
@@ -391,7 +391,7 @@ class File extends Container, @file {
* "tar.gz", while `getExtension` will have the result "gz". * "tar.gz", while `getExtension` will have the result "gz".
*/ */
string getExtensions() { string getExtensions() {
files(this,_,_,result,_) files(unresolveElement(this),_,_,result,_)
} }
/** /**
@@ -424,7 +424,7 @@ class File extends Container, @file {
* for example, for "file.tar.gz", this predicate will have the result * for example, for "file.tar.gz", this predicate will have the result
* "file", while `getStem` will have the result "file.tar". * "file", while `getStem` will have the result "file.tar".
*/ */
string getShortName() { files(this,_,result,_,_) } string getShortName() { files(unresolveElement(this),_,result,_,_) }
} }

View File

@@ -33,7 +33,7 @@ class FriendDecl extends Declaration, @frienddecl {
override Location getDefinitionLocation() { result = this.getLocation() } override Location getDefinitionLocation() { result = this.getLocation() }
/** Gets the location of this friend declaration. */ /** Gets the location of this friend declaration. */
override Location getLocation() { frienddecls(this,_,_,result) } override Location getLocation() { frienddecls(unresolveElement(this),_,_,result) }
/** Gets a descriptive string for this friend declaration. */ /** Gets a descriptive string for this friend declaration. */
override string getName() { override string getName() {
@@ -51,13 +51,13 @@ class FriendDecl extends Declaration, @frienddecl {
* Gets the target of this friend declaration. * Gets the target of this friend declaration.
* For example: `X` in `class A { friend class X }`. * For example: `X` in `class A { friend class X }`.
*/ */
AccessHolder getFriend() { frienddecls(this,_,result,_) } AccessHolder getFriend() { frienddecls(unresolveElement(this),_,unresolveElement(result),_) }
/** /**
* Gets the declaring class (also known as the befriending class). * Gets the declaring class (also known as the befriending class).
* For example: `A` in `class A { friend class X }`. * For example: `A` in `class A { friend class X }`.
*/ */
Class getDeclaringClass() { frienddecls(this,unresolve(result),_,_) } Class getDeclaringClass() { frienddecls(unresolveElement(this),unresolveElement(result),_,_) }
/* Holds if this declaration is a top-level declaration. */ /* Holds if this declaration is a top-level declaration. */
override predicate isTopLevel() { none() } override predicate isTopLevel() { none() }

View File

@@ -30,7 +30,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* To test whether a function has a particular name in the global * To test whether a function has a particular name in the global
* namespace, use `hasGlobalName`. * namespace, use `hasGlobalName`.
*/ */
override string getName() { functions(this,result,_) } override string getName() { functions(unresolveElement(this),result,_) }
/** /**
* Gets the full signature of this function, including return type, parameter * Gets the full signature of this function, including return type, parameter
@@ -70,16 +70,16 @@ 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(this,result) funspecifiers(unresolveElement(this),unresolveElement(result))
or result.hasName(getADeclarationEntry().getASpecifier()) or result.hasName(getADeclarationEntry().getASpecifier())
} }
/** Gets an attribute of this function. */ /** Gets an attribute of this function. */
Attribute getAnAttribute() { funcattributes(this, result) } Attribute getAnAttribute() { funcattributes(unresolveElement(this), unresolveElement(result)) }
/** Holds if this function is generated by the compiler. */ /** Holds if this function is generated by the compiler. */
predicate isCompilerGenerated() { predicate isCompilerGenerated() {
compgenerated(this) compgenerated(unresolveElement(this))
} }
/** Holds if this function is inline. */ /** Holds if this function is inline. */
@@ -104,7 +104,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* whether a class would have had those members implicitly deleted. * whether a class would have had those members implicitly deleted.
*/ */
predicate isDeleted() { predicate isDeleted() {
function_deleted(this) function_deleted(unresolveElement(this))
} }
/** /**
@@ -112,7 +112,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* specifier. * specifier.
*/ */
predicate isDefaulted() { predicate isDefaulted() {
function_defaulted(this) function_defaulted(unresolveElement(this))
} }
/** /**
@@ -124,13 +124,13 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
} }
/** Gets the return type of this function. */ /** Gets the return type of this function. */
Type getType() { function_return_type(this,unresolve(result)) } Type getType() { function_return_type(unresolveElement(this),unresolveElement(result)) }
/** Gets the nth parameter of this function. */ /** Gets the nth parameter of this function. */
Parameter getParameter(int n) { params(result,this,n,_) } Parameter getParameter(int n) { params(unresolveElement(result),unresolveElement(this),n,_) }
/** Gets a parameter of this function. */ /** Gets a parameter of this function. */
Parameter getAParameter() { params(result,this,_,_) } Parameter getAParameter() { params(unresolveElement(result),unresolveElement(this),_,_) }
/** /**
* Gets the number of parameters of this function, _not_ including any * Gets the number of parameters of this function, _not_ including any
@@ -183,14 +183,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* in `Declaration.qll`. * in `Declaration.qll`.
*/ */
override FunctionDeclarationEntry getADeclarationEntry() { override FunctionDeclarationEntry getADeclarationEntry() {
if fun_decls(_,this,_,_,_) then if fun_decls(_,unresolveElement(this),_,_,_) then
declEntry(result) declEntry(result)
else else
exists(Function f | this.isConstructedFrom(f) and fun_decls(result,f,_,_,_)) exists(Function f | this.isConstructedFrom(f) and fun_decls(unresolveElement(result),unresolveElement(f),_,_,_))
} }
private predicate declEntry(FunctionDeclarationEntry fde) { private predicate declEntry(FunctionDeclarationEntry fde) {
fun_decls(fde,this,_,_,_) and fun_decls(unresolveElement(fde),unresolveElement(this),_,_,_) and
// If one .cpp file specializes a function, and another calls the // If one .cpp file specializes a function, and another calls the
// specialized function, then when extracting the second we only see an // specialized function, then when extracting the second we only see an
// instantiation, not the specialization. We Therefore need to ignore // instantiation, not the specialization. We Therefore need to ignore
@@ -208,7 +208,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
/** Holds if this Function is a Template specialization. */ /** Holds if this Function is a Template specialization. */
predicate isSpecialization() { predicate isSpecialization() {
exists(FunctionDeclarationEntry fde | fun_decls(fde,this,_,_,_) exists(FunctionDeclarationEntry fde | fun_decls(unresolveElement(fde),unresolveElement(this),_,_,_)
and fde.isSpecialization()) and fde.isSpecialization())
} }
@@ -263,7 +263,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* `FunctionTryStmt`. * `FunctionTryStmt`.
*/ */
Stmt getEntryPoint() { Stmt getEntryPoint() {
function_entry_point(this, result) function_entry_point(unresolveElement(this), unresolveElement(result))
} }
/** /**
@@ -341,7 +341,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* function or from a function nested in a template class. * function or from a function nested in a template class.
*/ */
predicate isConstructedFrom(Function f) { predicate isConstructedFrom(Function f) {
function_instantiation(this, f) function_instantiation(unresolveElement(this), unresolveElement(f))
} }
/** /**
@@ -357,7 +357,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
* template class. * template class.
*/ */
Type getTemplateArgument(int index) { Type getTemplateArgument(int index) {
function_template_argument(this,index,unresolve(result)) function_template_argument(unresolveElement(this),index,unresolveElement(result))
} }
/** /**
@@ -496,22 +496,22 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
override Function getDeclaration() { result = getFunction() } override Function getDeclaration() { result = getFunction() }
/** Gets the function which is being declared or defined. */ /** Gets the function which is being declared or defined. */
Function getFunction() { fun_decls(this,result,_,_,_) } Function getFunction() { fun_decls(unresolveElement(this),unresolveElement(result),_,_,_) }
/** Gets the name of the function. */ /** Gets the name of the function. */
override string getName() { fun_decls(this,_,_,result,_) } override string getName() { fun_decls(unresolveElement(this),_,_,result,_) }
/** /**
* Gets the return type of the function which is being declared or * Gets the return type of the function which is being declared or
* defined. * defined.
*/ */
override Type getType() { fun_decls(this,_,unresolve(result),_,_) } override Type getType() { fun_decls(unresolveElement(this),_,unresolveElement(result),_,_) }
/** Gets the location of this declaration entry. */ /** Gets the location of this declaration entry. */
override Location getLocation() { fun_decls(this,_,_,_,result) } override Location getLocation() { fun_decls(unresolveElement(this),_,_,_,result) }
/** Gets a specifier associated with this declaration entry. */ /** Gets a specifier associated with this declaration entry. */
override string getASpecifier() { fun_decl_specifiers(this,result) } override string getASpecifier() { fun_decl_specifiers(unresolveElement(this),result) }
/** /**
* Implements `Element.getEnclosingElement`. A function declaration does * Implements `Element.getEnclosingElement`. A function declaration does
@@ -528,7 +528,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* static Foo foo; * static Foo foo;
*/ */
TypedefType getTypedefType() { TypedefType getTypedefType() {
fun_decl_typedef_type(this,result) fun_decl_typedef_type(unresolveElement(this),unresolveElement(result))
} }
/** /**
@@ -578,7 +578,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* declaration. * declaration.
*/ */
ParameterDeclarationEntry getParameterDeclarationEntry(int n) { ParameterDeclarationEntry getParameterDeclarationEntry(int n) {
param_decl_bind(result,n,this) param_decl_bind(unresolveElement(result),n,unresolveElement(this))
} }
/** Gets the number of parameters of this function declaration. */ /** Gets the number of parameters of this function declaration. */
@@ -624,12 +624,12 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** 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() { override predicate isDefinition() {
fun_def(this) fun_def(unresolveElement(this))
} }
/** Holds if this declaration is a Template specialization. */ /** Holds if this declaration is a Template specialization. */
predicate isSpecialization() { predicate isSpecialization() {
fun_specialized(this) fun_specialized(unresolveElement(this))
} }
/** /**
@@ -637,7 +637,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* where a function is used before it is declared (under older C standards). * where a function is used before it is declared (under older C standards).
*/ */
predicate isImplicit() { predicate isImplicit() {
fun_implicit(this) fun_implicit(unresolveElement(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. */
@@ -652,7 +652,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* `int`, and that with index 1 would be `float`. * `int`, and that with index 1 would be `float`.
*/ */
Type getThrownType(int i) { Type getThrownType(int i) {
fun_decl_throws(this,i,unresolve(result)) fun_decl_throws(unresolveElement(this),i,unresolveElement(result))
} }
/** /**
@@ -660,7 +660,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* this predicate returns the argument to `noexcept` if one was given. * this predicate returns the argument to `noexcept` if one was given.
*/ */
Expr getNoExceptExpr() { Expr getNoExceptExpr() {
fun_decl_noexcept(this,result) fun_decl_noexcept(unresolveElement(this),unresolveElement(result))
} }
/** /**
@@ -668,8 +668,8 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* 15.4]. * 15.4].
*/ */
predicate hasExceptionSpecification() { predicate hasExceptionSpecification() {
fun_decl_throws(this,_,_) or fun_decl_throws(unresolveElement(this),_,_) or
fun_decl_noexcept(this,_) or fun_decl_noexcept(unresolveElement(this),_) or
isNoThrow() or isNoThrow() or
isNoExcept() isNoExcept()
} }
@@ -678,7 +678,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* Holds if the declared function has a `throw()` exception specification. * Holds if the declared function has a `throw()` exception specification.
*/ */
predicate isNoThrow() { predicate isNoThrow() {
fun_decl_empty_throws(this) fun_decl_empty_throws(unresolveElement(this))
} }
/** /**
@@ -686,7 +686,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* specification. * specification.
*/ */
predicate isNoExcept() { predicate isNoExcept() {
fun_decl_empty_noexcept(this) fun_decl_empty_noexcept(unresolveElement(this))
} }
} }
@@ -731,7 +731,7 @@ class MemberFunction extends Function {
predicate isPublic() { this.hasSpecifier("public") } predicate isPublic() { this.hasSpecifier("public") }
/** Holds if this function overrides that function. */ /** Holds if this function overrides that function. */
predicate overrides(MemberFunction that) { overrides(this,that) } predicate overrides(MemberFunction that) { overrides(unresolveElement(this),unresolveElement(that)) }
/** Gets a directly overridden function. */ /** Gets a directly overridden function. */
MemberFunction getAnOverriddenFunction() { this.overrides(result) } MemberFunction getAnOverriddenFunction() { this.overrides(result) }
@@ -758,7 +758,7 @@ class MemberFunction extends Function {
class VirtualFunction extends MemberFunction { class VirtualFunction extends MemberFunction {
VirtualFunction() { VirtualFunction() {
this.hasSpecifier("virtual") or purefunctions(this) this.hasSpecifier("virtual") or purefunctions(unresolveElement(this))
} }
/** Holds if this virtual function is pure. */ /** Holds if this virtual function is pure. */
@@ -776,7 +776,7 @@ class VirtualFunction extends MemberFunction {
*/ */
class PureVirtualFunction extends VirtualFunction { class PureVirtualFunction extends VirtualFunction {
PureVirtualFunction() { purefunctions(this) } PureVirtualFunction() { purefunctions(unresolveElement(this)) }
} }
@@ -796,7 +796,7 @@ class ConstMemberFunction extends MemberFunction {
*/ */
class Constructor extends MemberFunction { class Constructor extends MemberFunction {
Constructor() { functions(this,_,2) } Constructor() { functions(unresolveElement(this),_,2) }
/** /**
* Holds if this constructor serves as a default constructor. * Holds if this constructor serves as a default constructor.
@@ -825,7 +825,7 @@ class Constructor extends MemberFunction {
* to be evaluated. * to be evaluated.
*/ */
ConstructorInit getInitializer(int i) { ConstructorInit getInitializer(int i) {
exprparents(result, i, this) exprparents(unresolveElement(result), i, unresolveElement(this))
} }
} }
@@ -976,7 +976,7 @@ class NoArgConstructor extends Constructor {
* A C++ destructor [N4140 12.4]. * A C++ destructor [N4140 12.4].
*/ */
class Destructor extends MemberFunction { class Destructor extends MemberFunction {
Destructor() { functions(this,_,3) } Destructor() { functions(unresolveElement(this),_,3) }
/** /**
* Gets a compiler-generated action which destructs a base class or member * Gets a compiler-generated action which destructs a base class or member
@@ -992,7 +992,7 @@ class Destructor extends MemberFunction {
* be evaluated. * be evaluated.
*/ */
DestructorDestruction getDestruction(int i) { DestructorDestruction getDestruction(int i) {
exprparents(result, i, this) exprparents(unresolveElement(result), i, unresolveElement(this))
} }
} }
@@ -1001,7 +1001,7 @@ class Destructor extends MemberFunction {
*/ */
class ConversionOperator extends MemberFunction, ImplicitConversionFunction { class ConversionOperator extends MemberFunction, ImplicitConversionFunction {
ConversionOperator() { functions(this,_,4) } ConversionOperator() { functions(unresolveElement(this),_,4) }
override Type getSourceType() { result = this.getDeclaringType() } override Type getSourceType() { result = this.getDeclaringType() }
override Type getDestType() { result = this.getType() } override Type getDestType() { result = this.getType() }
@@ -1013,7 +1013,7 @@ class ConversionOperator extends MemberFunction, ImplicitConversionFunction {
*/ */
class Operator extends Function { class Operator extends Function {
Operator() { functions(this,_,5) } Operator() { functions(unresolveElement(this),_,5) }
} }
@@ -1074,7 +1074,7 @@ class MoveAssignmentOperator extends Operator {
* (non-empty) template argument list. * (non-empty) template argument list.
*/ */
class TemplateFunction extends Function { class TemplateFunction extends Function {
TemplateFunction() { is_function_template(this) and exists(getATemplateArgument()) } TemplateFunction() { is_function_template(unresolveElement(this)) and exists(getATemplateArgument()) }
/** /**
* Gets a compiler-generated instantiation of this function template. * Gets a compiler-generated instantiation of this function template.
@@ -1146,7 +1146,7 @@ class FunctionTemplateSpecialization extends Function {
*/ */
class BuiltInFunction extends Function { class BuiltInFunction extends Function {
BuiltInFunction() { BuiltInFunction() {
functions(this,_,6) functions(unresolveElement(this),_,6)
} }
/** Gets a dummy location for the built-in function. */ /** Gets a dummy location for the built-in function. */

View File

@@ -14,7 +14,7 @@ class Include extends PreprocessorDirective, @ppd_include {
string getIncludeText() { result = getHead() } string getIncludeText() { result = getHead() }
/** Gets the file directly included by this `#include`. */ /** Gets the file directly included by this `#include`. */
File getIncludedFile() { includes(this, result) } File getIncludedFile() { includes(unresolveElement(this), unresolveElement(result)) }
/** /**
* Gets a file which might be transitively included by this `#include`. * Gets a file which might be transitively included by this `#include`.

View File

@@ -3,8 +3,8 @@ import semmle.code.cpp.controlflow.ControlFlowGraph
/** /**
* A C/C++ declaration initializer. * A C/C++ declaration initializer.
*/ */
class Initializer extends @initialiser, ControlFlowNode { class Initializer extends ControlFlowNode, @initialiser {
override Location getLocation() { initialisers(this,_,_,result) } override Location getLocation() { initialisers(unresolveElement(this),_,_,result) }
/** Holds if this initializer is explicit in the source. */ /** Holds if this initializer is explicit in the source. */
override predicate fromSource() { override predicate fromSource() {
@@ -20,10 +20,10 @@ class Initializer extends @initialiser, ControlFlowNode {
} }
/** Gets the variable or enum constant being initialized. */ /** Gets the variable or enum constant being initialized. */
Declaration getDeclaration() { initialisers(this,result,_,_) } Declaration getDeclaration() { initialisers(unresolveElement(this),unresolveElement(result),_,_) }
/** Gets the initializing expression. */ /** Gets the initializing expression. */
Expr getExpr() { initialisers(this,_,result,_) } Expr getExpr() { initialisers(unresolveElement(this),_,unresolveElement(result),_) }
/** Gets the function containing this control-flow node. */ /** Gets the function containing this control-flow node. */
override Function getControlFlowScope() { override Function getControlFlowScope() {

View File

@@ -14,7 +14,7 @@ class LinkTarget extends @link_target {
* Gets the file which was built. * Gets the file which was built.
*/ */
File getBinary() { File getBinary() {
link_targets(this, result) link_targets(this, unresolveElement(result))
} }
/** /**
@@ -37,7 +37,7 @@ class LinkTarget extends @link_target {
* to this link target. * to this link target.
*/ */
Function getAFunction() { Function getAFunction() {
link_parent(result, this) link_parent(unresolveElement(result), this)
} }
/** /**
@@ -45,7 +45,7 @@ class LinkTarget extends @link_target {
* translation units which contributed to this link target. * translation units which contributed to this link target.
*/ */
Class getAClass() { Class getAClass() {
link_parent(result, this) link_parent(unresolveElement(result), this)
} }
} }

View File

@@ -58,9 +58,9 @@ class Location extends @location {
*/ */
predicate fullLocationInfo( predicate fullLocationInfo(
Container container, int startline, int startcolumn, int endline, int endcolumn) { Container container, int startline, int startcolumn, int endline, int endcolumn) {
locations_default(this, container, startline, startcolumn, endline, endcolumn) or locations_default(this, unresolveElement(container), startline, startcolumn, endline, endcolumn) or
locations_expr(this, container, startline, startcolumn, endline, endcolumn) or locations_expr(this, unresolveElement(container), startline, startcolumn, endline, endcolumn) or
locations_stmt(this, container, startline, startcolumn, endline, endcolumn) locations_stmt(this, unresolveElement(container), startline, startcolumn, endline, endcolumn)
} }
/** /**

View File

@@ -9,13 +9,13 @@ class Macro extends PreprocessorDirective, @ppd_define {
* Gets the head of this macro. For example, `MAX(x,y)` in * Gets the head of this macro. For example, `MAX(x,y)` in
* `#define MAX(x,y) (((x)>(y))?(x):(y))`. * `#define MAX(x,y) (((x)>(y))?(x):(y))`.
*/ */
override string getHead() { preproctext(this,result,_) } override string getHead() { preproctext(unresolveElement(this),result,_) }
/** /**
* Gets the body of this macro. For example, `(((x)>(y))?(x):(y))` in * Gets the body of this macro. For example, `(((x)>(y))?(x):(y))` in
* `#define MAX(x,y) (((x)>(y))?(x):(y))`. * `#define MAX(x,y) (((x)>(y))?(x):(y))`.
*/ */
string getBody() { preproctext(this,_,result) } string getBody() { preproctext(unresolveElement(this),_,result) }
/** Gets an invocation of this macro. */ /** Gets an invocation of this macro. */
MacroInvocation getAnInvocation() { result.getMacro() = this } MacroInvocation getAnInvocation() { result.getMacro() = this }
@@ -59,7 +59,7 @@ class Macro extends PreprocessorDirective, @ppd_define {
*/ */
class MacroAccess extends Locatable, @macroinvocation { class MacroAccess extends Locatable, @macroinvocation {
/** Gets the macro being invoked. */ /** Gets the macro being invoked. */
Macro getMacro() { macroinvocations(this,result,_,_) } Macro getMacro() { macroinvocations(unresolveElement(this),unresolveElement(result),_,_) }
/** /**
* Gets the location of the outermost macro access that triggered this macro * Gets the location of the outermost macro access that triggered this macro
@@ -78,7 +78,7 @@ class MacroAccess extends Locatable, @macroinvocation {
* a `#define` directive or inside an argument to another macro. * a `#define` directive or inside an argument to another macro.
*/ */
Location getActualLocation() { Location getActualLocation() {
macroinvocations(this,_,result,_) macroinvocations(unresolveElement(this),_,result,_)
} }
/** /**
@@ -111,7 +111,7 @@ class MacroAccess extends Locatable, @macroinvocation {
* There is only a single invocation even though `c` occurs twice; this is an * There is only a single invocation even though `c` occurs twice; this is an
* optimization for efficiency. * optimization for efficiency.
*/ */
MacroInvocation getParentInvocation() { macroparent(this,result) } MacroInvocation getParentInvocation() { macroparent(unresolveElement(this),unresolveElement(result)) }
/** /**
* Gets the outermost `MacroAccess` along the chain of `getParentInvocation`. * Gets the outermost `MacroAccess` along the chain of `getParentInvocation`.
@@ -137,14 +137,14 @@ class MacroAccess extends Locatable, @macroinvocation {
*/ */
class MacroInvocation extends MacroAccess { class MacroInvocation extends MacroAccess {
MacroInvocation() { MacroInvocation() {
macroinvocations(this,_,_,1) macroinvocations(unresolveElement(this),_,_,1)
} }
/** /**
* Gets an element that occurs in this macro invocation or a nested macro * Gets an element that occurs in this macro invocation or a nested macro
* invocation. * invocation.
*/ */
Locatable getAnExpandedElement() { inmacroexpansion(result,this) } Locatable getAnExpandedElement() { inmacroexpansion(unresolveElement(result),unresolveElement(this)) }
/** /**
* Gets an element that is (partially) affected by a macro * Gets an element that is (partially) affected by a macro
@@ -153,7 +153,7 @@ class MacroInvocation extends MacroAccess {
* well. * well.
*/ */
Locatable getAnAffectedElement() { Locatable getAnAffectedElement() {
inmacroexpansion(result,this) or macrolocationbind(this, result.getLocation()) inmacroexpansion(unresolveElement(result),unresolveElement(this)) or macrolocationbind(unresolveElement(this), result.getLocation())
} }
/** /**
@@ -224,7 +224,7 @@ class MacroInvocation extends MacroAccess {
* Use `getExpandedArgument` to get the expanded form. * Use `getExpandedArgument` to get the expanded form.
*/ */
string getUnexpandedArgument(int i) { string getUnexpandedArgument(int i) {
macro_argument_unexpanded(this, i, result) macro_argument_unexpanded(unresolveElement(this), i, result)
} }
/** /**
@@ -238,7 +238,7 @@ class MacroInvocation extends MacroAccess {
* differences between expanded and unexpanded arguments. * differences between expanded and unexpanded arguments.
*/ */
string getExpandedArgument(int i) { string getExpandedArgument(int i) {
macro_argument_expanded(this, i, result) macro_argument_expanded(unresolveElement(this), i, result)
} }
} }
@@ -291,7 +291,7 @@ predicate macroLocation(Location l) {
/** Holds if `element` is in the expansion of a macro. */ /** Holds if `element` is in the expansion of a macro. */
predicate inMacroExpansion(Locatable element) { predicate inMacroExpansion(Locatable element) {
inmacroexpansion(element,_) or inmacroexpansion(unresolveElement(element),_) or
(macroLocation(element.getLocation()) and (macroLocation(element.getLocation()) and
not topLevelMacroAccess(element)) not topLevelMacroAccess(element))
} }
@@ -317,7 +317,7 @@ predicate inSystemMacroExpansion(Locatable element) {
/** Holds if `element` is affected by a macro. */ /** Holds if `element` is affected by a macro. */
predicate affectedByMacro(Locatable element) { predicate affectedByMacro(Locatable element) {
inMacroExpansion(element) or inMacroExpansion(element) or
affectedbymacroexpansion(element,_) affectedbymacroexpansion(unresolveElement(element),_)
} }
/** Holds if there is a macro invocation on line `line` of file `f`. */ /** Holds if there is a macro invocation on line `line` of file `f`. */

View File

@@ -14,7 +14,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
/** Gets a location for this name qualifier. */ /** Gets a location for this name qualifier. */
override Location getLocation() { override Location getLocation() {
namequalifiers(this,_,_,result) namequalifiers(unresolveElement(this),_,_,result)
} }
/** /**
@@ -23,7 +23,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
* `N2::` has a name qualifier `N1::` in the chain `N1::N2::f()`. * `N2::` has a name qualifier `N1::` in the chain `N1::N2::f()`.
*/ */
override NameQualifier getNameQualifier() { override NameQualifier getNameQualifier() {
namequalifiers(result,this,_,_) namequalifiers(unresolveElement(result),unresolveElement(this),_,_)
} }
/** /**
@@ -31,7 +31,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
* in `N::f()`. * in `N::f()`.
*/ */
NameQualifiableElement getQualifiedElement() { NameQualifiableElement getQualifiedElement() {
namequalifiers(this,result,_,_) namequalifiers(unresolveElement(this),unresolveElement(result),_,_)
} }
/** /**
@@ -40,7 +40,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
*/ */
NameQualifyingElement getQualifyingElement() { NameQualifyingElement getQualifyingElement() {
exists (NameQualifyingElement nqe exists (NameQualifyingElement nqe
| namequalifiers(this,_,nqe,_) and | namequalifiers(unresolveElement(this),_,unresolveElement(nqe),_) and
if nqe instanceof SpecialNameQualifyingElement if nqe instanceof SpecialNameQualifyingElement
then (exists (Access a then (exists (Access a
| a = getQualifiedElement() and | a = getQualifiedElement() and
@@ -54,7 +54,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
override string toString() { override string toString() {
exists (NameQualifyingElement nqe exists (NameQualifyingElement nqe
| namequalifiers(this,_,nqe,_) | namequalifiers(unresolveElement(this),_,unresolveElement(nqe),_)
and result = nqe.getName() + "::") and result = nqe.getName() + "::")
} }
} }
@@ -69,7 +69,7 @@ class NameQualifier extends NameQualifiableElement, @namequalifier {
class NameQualifiableElement extends Element, @namequalifiableelement { class NameQualifiableElement extends Element, @namequalifiableelement {
/** Gets the name qualifier associated with this element. */ /** Gets the name qualifier associated with this element. */
NameQualifier getNameQualifier() { NameQualifier getNameQualifier() {
namequalifiers(result,this,_,_) namequalifiers(unresolveElement(result),unresolveElement(this),_,_)
} }
/** /**
@@ -89,7 +89,7 @@ class NameQualifiableElement extends Element, @namequalifiableelement {
predicate hasSuperQualifiedName() { predicate hasSuperQualifiedName() {
exists(NameQualifier nq, SpecialNameQualifyingElement snqe | exists(NameQualifier nq, SpecialNameQualifyingElement snqe |
nq = getNameQualifier*() nq = getNameQualifier*()
and namequalifiers(nq,_,snqe,_) and namequalifiers(unresolveElement(nq),_,unresolveElement(snqe),_)
and snqe.getName() = "__super" and snqe.getName() = "__super"
) )
} }
@@ -106,7 +106,7 @@ class NameQualifyingElement extends Element, @namequalifyingelement {
* `NameQualifyingElement` and `X::` is the `NameQualifier`. * `NameQualifyingElement` and `X::` is the `NameQualifier`.
*/ */
NameQualifier getANameQualifier() { NameQualifier getANameQualifier() {
namequalifiers(result,_,this,_) namequalifiers(unresolveElement(result),_,unresolveElement(this),_)
} }
/** Gets the name of this namespace or user-defined type. */ /** Gets the name of this namespace or user-defined type. */
@@ -121,6 +121,6 @@ class NameQualifyingElement extends Element, @namequalifyingelement {
library class SpecialNameQualifyingElement extends NameQualifyingElement, @specialnamequalifyingelement { library class SpecialNameQualifyingElement extends NameQualifyingElement, @specialnamequalifyingelement {
/** Gets the name of this special qualifying element. */ /** Gets the name of this special qualifying element. */
override string getName() { override string getName() {
specialnamequalifyingelements(this,result) specialnamequalifyingelements(unresolveElement(this),result)
} }
} }

View File

@@ -31,7 +31,7 @@ class Namespace extends NameQualifyingElement, @namespace {
} }
/** Gets the simple name of this namespace. */ /** Gets the simple name of this namespace. */
override string getName() { namespaces(this,result) } override string getName() { namespaces(unresolveElement(this),result) }
/** Holds if this element is named `name`. */ /** Holds if this element is named `name`. */
predicate hasName(string name) { name = this.getName() } predicate hasName(string name) { name = this.getName() }
@@ -56,15 +56,15 @@ class Namespace extends NameQualifyingElement, @namespace {
/** Gets the parent namespace, if any. */ /** Gets the parent namespace, if any. */
Namespace getParentNamespace() { Namespace getParentNamespace() {
namespacembrs(result,this) or namespacembrs(unresolveElement(result),unresolveElement(this)) or
(not namespacembrs(_, this) and result instanceof GlobalNamespace) (not namespacembrs(_, unresolveElement(this)) and result instanceof GlobalNamespace)
} }
/** Gets a child declaration of this namespace. */ /** Gets a child declaration of this namespace. */
Declaration getADeclaration() { namespacembrs(this,result) } Declaration getADeclaration() { namespacembrs(unresolveElement(this),unresolveElement(result)) }
/** Gets a child namespace of this namespace. */ /** Gets a child namespace of this namespace. */
Namespace getAChildNamespace() { namespacembrs(this,result) } Namespace getAChildNamespace() { namespacembrs(unresolveElement(this),unresolveElement(result)) }
/** Holds if this namespace may be from source. */ /** Holds if this namespace may be from source. */
override predicate fromSource() { this.getADeclaration().fromSource() } override predicate fromSource() { this.getADeclaration().fromSource() }
@@ -106,7 +106,7 @@ class NamespaceDeclarationEntry extends Locatable, @namespace_decl {
* is a one-to-many relationship between `Namespace` and * is a one-to-many relationship between `Namespace` and
* `NamespaceDeclarationEntry`. * `NamespaceDeclarationEntry`.
*/ */
Namespace getNamespace() { namespace_decls(this,result,_,_) } Namespace getNamespace() { namespace_decls(unresolveElement(this),unresolveElement(result),_,_) }
override string toString() { result = this.getNamespace().toString() } override string toString() { result = this.getNamespace().toString() }
@@ -120,20 +120,20 @@ class NamespaceDeclarationEntry extends Locatable, @namespace_decl {
* For anonymous declarations, such as "namespace { ... }", this will * For anonymous declarations, such as "namespace { ... }", this will
* give the "namespace" token. * give the "namespace" token.
*/ */
override Location getLocation() { namespace_decls(this,_,result,_) } override Location getLocation() { namespace_decls(unresolveElement(this),_,result,_) }
/** /**
* Gets the location of the namespace declaration entry's body. For * Gets the location of the namespace declaration entry's body. For
* example: the "{ ... }" in "namespace N { ... }". * example: the "{ ... }" in "namespace N { ... }".
*/ */
Location getBodyLocation() { namespace_decls(this,_,_,result) } Location getBodyLocation() { namespace_decls(unresolveElement(this),_,_,result) }
} }
/** /**
* A C++ `using` directive or `using` declaration. * A C++ `using` directive or `using` declaration.
*/ */
abstract class UsingEntry extends Locatable, @using { abstract class UsingEntry extends Locatable, @using {
override Location getLocation() { usings(this,_,result) } override Location getLocation() { usings(unresolveElement(this),_,result) }
} }
/** /**
@@ -142,13 +142,13 @@ abstract class UsingEntry extends Locatable, @using {
* `using std::string;` * `using std::string;`
*/ */
class UsingDeclarationEntry extends UsingEntry { class UsingDeclarationEntry extends UsingEntry {
UsingDeclarationEntry() { not exists(Namespace n | usings(this,n,_)) } UsingDeclarationEntry() { not exists(Namespace n | usings(unresolveElement(this),unresolveElement(n),_)) }
/** /**
* Gets the declaration that is referenced by this using declaration. For * Gets the declaration that is referenced by this using declaration. For
* example, `std::string` in `using std::string`. * example, `std::string` in `using std::string`.
*/ */
Declaration getDeclaration() { usings(this,result,_) } Declaration getDeclaration() { usings(unresolveElement(this),unresolveElement(result),_) }
override string toString() { override string toString() {
result = "using " + this.getDeclaration().toString() result = "using " + this.getDeclaration().toString()
@@ -161,13 +161,13 @@ class UsingDeclarationEntry extends UsingEntry {
* `using namespace std;` * `using namespace std;`
*/ */
class UsingDirectiveEntry extends UsingEntry { class UsingDirectiveEntry extends UsingEntry {
UsingDirectiveEntry() { exists(Namespace n | usings(this,n,_)) } UsingDirectiveEntry() { exists(Namespace n | usings(unresolveElement(this),unresolveElement(n),_)) }
/** /**
* Gets the namespace that is referenced by this using directive. For * Gets the namespace that is referenced by this using directive. For
* example, `std` in `using namespace std`. * example, `std` in `using namespace std`.
*/ */
Namespace getNamespace() { usings(this,result,_) } Namespace getNamespace() { usings(unresolveElement(this),unresolveElement(result),_) }
override string toString() { override string toString() {
result = "using namespace " + this.getNamespace().toString() result = "using namespace " + this.getNamespace().toString()
@@ -200,14 +200,14 @@ class GlobalNamespace extends Namespace {
not result instanceof ProxyClass and not result instanceof ProxyClass and
not result instanceof TemplateParameter and not result instanceof TemplateParameter and
not result instanceof LocalVariable and not result instanceof LocalVariable and
not namespacembrs(_, result) and not namespacembrs(_, unresolveElement(result)) and
not result.isMember() not result.isMember()
} }
/** Gets a child namespace of the global namespace. */ /** Gets a child namespace of the global namespace. */
override Namespace getAChildNamespace() { override Namespace getAChildNamespace() {
suppressWarningForUnused(this) and suppressWarningForUnused(this) and
not (namespacembrs(result, _)) not (namespacembrs(unresolveElement(result), _))
} }
override Namespace getParentNamespace() { override Namespace getParentNamespace() {

View File

@@ -102,20 +102,20 @@ class Parameter extends LocalScopeVariable, @parameter {
* 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
* parameter. * parameter.
*/ */
override Function getFunction() { params(this,result,_,_) } override Function getFunction() { params(unresolveElement(this),unresolveElement(result),_,_) }
/** /**
* Gets the catch block to which this parameter belongs, if it is a catch * Gets the catch block to which this parameter belongs, if it is a catch
* block parameter. * block parameter.
*/ */
Block getCatchBlock() { params(this,result,_,_) } Block getCatchBlock() { params(unresolveElement(this),unresolveElement(result),_,_) }
/** /**
* Gets the zero-based index of this parameter. * Gets the zero-based index of this parameter.
* *
* For catch block parameters, this is always zero. * For catch block parameters, this is always zero.
*/ */
int getIndex() { params(this,_,result,_) } int getIndex() { params(unresolveElement(this),_,result,_) }
/** /**
* Gets the type of this parameter. * Gets the type of this parameter.
@@ -124,7 +124,7 @@ class Parameter extends LocalScopeVariable, @parameter {
* as they are syntactic sugar for parameters of pointer type. The * as they are syntactic sugar for parameters of pointer type. The
* result is an array type for such parameters. * result is an array type for such parameters.
*/ */
override Type getType() { params(this,_,_,unresolve(result)) } override Type getType() { params(unresolveElement(this),_,_,unresolveElement(result)) }
/** /**
* Gets the canonical location, or locations, of this parameter. * Gets the canonical location, or locations, of this parameter.

View File

@@ -8,8 +8,8 @@ import semmle.code.cpp.Element
*/ */
class PreprocessorDirective extends Locatable, @preprocdirect { class PreprocessorDirective extends Locatable, @preprocdirect {
override string toString() { result = "Preprocessor directive" } override string toString() { result = "Preprocessor directive" }
override Location getLocation() { preprocdirects(this,_,result) } override Location getLocation() { preprocdirects(unresolveElement(this),_,result) }
string getHead() { preproctext(this,result,_) } string getHead() { preproctext(unresolveElement(this),result,_) }
/** /**
* Gets a preprocessor branching directive whose condition affects * Gets a preprocessor branching directive whose condition affects
@@ -49,7 +49,7 @@ abstract class PreprocessorBranchDirective extends PreprocessorDirective {
result = (PreprocessorIf)this or result = (PreprocessorIf)this or
result = (PreprocessorIfdef)this or result = (PreprocessorIfdef)this or
result = (PreprocessorIfndef)this or result = (PreprocessorIfndef)this or
preprocpair(result, this) preprocpair(unresolveElement(result), unresolveElement(this))
} }
/** /**
@@ -61,7 +61,7 @@ abstract class PreprocessorBranchDirective extends PreprocessorDirective {
* one result. * one result.
*/ */
PreprocessorEndif getEndIf() { PreprocessorEndif getEndIf() {
preprocpair(getIf(), result) preprocpair(unresolveElement(getIf()), unresolveElement(result))
} }
/** /**
@@ -106,7 +106,7 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* condition and subsequently took the branch. * condition and subsequently took the branch.
*/ */
predicate wasTaken() { predicate wasTaken() {
preproctrue(this) preproctrue(unresolveElement(this))
} }
/** /**
@@ -117,7 +117,7 @@ class PreprocessorBranch extends PreprocessorBranchDirective, @ppd_branch {
* `#else` was taken instead. * `#else` was taken instead.
*/ */
predicate wasNotTaken() { predicate wasNotTaken() {
preprocfalse(this) preprocfalse(unresolveElement(this))
} }
/** /**

View File

@@ -14,7 +14,7 @@ class Specifier extends Element, @specifier {
} }
/** Gets the name of this specifier. */ /** Gets the name of this specifier. */
string getName() { specifiers(this,result) } string getName() { specifiers(unresolveElement(this),result) }
/** Holds if the name of this specifier is `name`. */ /** Holds if the name of this specifier is `name`. */
predicate hasName(string name) { name = this.getName() } predicate hasName(string name) { name = this.getName() }
@@ -114,9 +114,9 @@ class Attribute extends Element, @attribute {
* Note that the name does not include the namespace. For example, the * Note that the name does not include the namespace. For example, the
* name of `[[clang::fallthrough]]` is "fallthrough". * name of `[[clang::fallthrough]]` is "fallthrough".
*/ */
string getName() { attributes(this, _, result, _, _) } string getName() { attributes(unresolveElement(this), _, result, _, _) }
override Location getLocation() { attributes(this, _, _, _, result) } override Location getLocation() { attributes(unresolveElement(this), _, _, _, result) }
/** Holds if the name of this attribute is `name`. */ /** Holds if the name of this attribute is `name`. */
predicate hasName(string name) { name = this.getName() } predicate hasName(string name) { name = this.getName() }
@@ -152,7 +152,7 @@ class StdAttribute extends Attribute, @stdattribute {
* As examples, this is "" for `[[carries_dependency]]`, and "clang" for * As examples, this is "" for `[[carries_dependency]]`, and "clang" for
* `[[clang::fallthrough]]`. * `[[clang::fallthrough]]`.
*/ */
string getNamespace() { attributes(this, _, _, result, _) } string getNamespace() { attributes(unresolveElement(this), _, _, result, _) }
/** /**
* Holds if this attribute has the given namespace and name. * Holds if this attribute has the given namespace and name.
@@ -249,7 +249,7 @@ class AttributeArgument extends Element, @attribute_arg {
* have a named argument. * have a named argument.
*/ */
string getName() { string getName() {
attribute_arg_name(this, result) attribute_arg_name(unresolveElement(this), result)
} }
/** /**
@@ -257,7 +257,7 @@ class AttributeArgument extends Element, @attribute_arg {
* a string or a number. * a string or a number.
*/ */
string getValueText() { string getValueText() {
attribute_arg_value(this, result) attribute_arg_value(unresolveElement(this), result)
} }
/** /**
@@ -271,14 +271,14 @@ class AttributeArgument extends Element, @attribute_arg {
* Gets the value of this argument, if its value is a type. * Gets the value of this argument, if its value is a type.
*/ */
Type getValueType() { Type getValueType() {
attribute_arg_type(this, unresolve(result)) attribute_arg_type(unresolveElement(this), unresolveElement(result))
} }
/** /**
* Gets the attribute to which this is an argument. * Gets the attribute to which this is an argument.
*/ */
Attribute getAttribute() { Attribute getAttribute() {
attribute_args(this, _, result, _, _) attribute_args(unresolveElement(this), _, unresolveElement(result), _, _)
} }
/** /**
@@ -286,21 +286,21 @@ class AttributeArgument extends Element, @attribute_arg {
* attribute's argument list. * attribute's argument list.
*/ */
int getIndex() { int getIndex() {
attribute_args(this, _, _, result, _) attribute_args(unresolveElement(this), _, _, result, _)
} }
override Location getLocation() { override Location getLocation() {
attribute_args(this, _, _, _, result) attribute_args(unresolveElement(this), _, _, _, result)
} }
override string toString() { override string toString() {
if exists (@attribute_arg_empty self | self = this) if exists (@attribute_arg_empty self | mkElement(self) = this)
then result = "empty argument" then result = "empty argument"
else exists (string prefix, string tail else exists (string prefix, string tail
| (if exists(getName()) | (if exists(getName())
then prefix = getName() + "=" then prefix = getName() + "="
else prefix = "") and else prefix = "") and
(if exists (@attribute_arg_type self | self = this) (if exists (@attribute_arg_type self | mkElement(self) = this)
then tail = getValueType().getName() then tail = getValueType().getName()
else tail = getValueText()) and else tail = getValueText()) and
result = prefix + tail) result = prefix + tail)

View File

@@ -6,7 +6,7 @@ import semmle.code.cpp.Class
*/ */
class Struct extends Class { class Struct extends Class {
Struct() { usertypes(this,_,1) or usertypes(this,_,3) } Struct() { usertypes(unresolveElement(this),_,1) or usertypes(unresolveElement(this),_,3) }
override string explain() { result = "struct " + this.getName() } override string explain() { result = "struct " + this.getName() }

View File

@@ -46,7 +46,7 @@ class Type extends Locatable, @type {
// inherits from both Type and Declaration and must override it to resolve // inherits from both Type and Declaration and must override it to resolve
// the ambiguity. // the ambiguity.
Specifier getASpecifier() { Specifier getASpecifier() {
typespecifiers(this,result) typespecifiers(unresolveElement(this),unresolveElement(result))
or or
result = this.internal_getAnAdditionalSpecifier() result = this.internal_getAnAdditionalSpecifier()
} }
@@ -54,7 +54,7 @@ class Type extends Locatable, @type {
/** /**
* Gets an attribute of this type. * Gets an attribute of this type.
*/ */
Attribute getAnAttribute() { typeattributes(this,result) } Attribute getAnAttribute() { typeattributes(unresolveElement(this),unresolveElement(result)) }
/** /**
* Internal -- should be `protected` when QL supports such a flag. Subtypes * Internal -- should be `protected` when QL supports such a flag. Subtypes
@@ -98,7 +98,7 @@ class Type extends Locatable, @type {
* *
* For example, starting with `const i64* const` in the context of `typedef long long i64;`, this predicate will return `long long*`. * For example, starting with `const i64* const` in the context of `typedef long long i64;`, this predicate will return `long long*`.
*/ */
Type getUnspecifiedType() { unspecifiedtype(this, unresolve(result)) } Type getUnspecifiedType() { unspecifiedtype(unresolveElement(this), unresolveElement(result)) }
/** /**
* Gets this type after any top-level specifiers and typedefs have been stripped. * Gets this type after any top-level specifiers and typedefs have been stripped.
@@ -111,18 +111,18 @@ class Type extends Locatable, @type {
* Gets the size of this type in bytes. * Gets the size of this type in bytes.
*/ */
int getSize() { int getSize() {
builtintypes(this, _, _, result, _, _) builtintypes(unresolveElement(this), _, _, result, _, _)
or pointerishsize(this, result, _) or pointerishsize(unresolveElement(this), result, _)
or usertypesize(this, result, _) or usertypesize(unresolveElement(this), result, _)
} }
/** /**
* Gets the alignment of this type in bytes. * Gets the alignment of this type in bytes.
*/ */
int getAlignment() { int getAlignment() {
builtintypes(this, _, _, _, _, result) builtintypes(unresolveElement(this), _, _, _, _, result)
or pointerishsize(this, _, result) or pointerishsize(unresolveElement(this), _, result)
or usertypesize(this, _, result) or usertypesize(unresolveElement(this), _, result)
} }
/** /**
@@ -306,7 +306,7 @@ class Type extends Locatable, @type {
class BuiltInType extends Type, @builtintype { class BuiltInType extends Type, @builtintype {
override string toString() { result = this.getName() } override string toString() { result = this.getName() }
override string getName() { builtintypes(this,result,_,_,_,_) } override string getName() { builtintypes(unresolveElement(this),result,_,_,_,_) }
override string explain() { result = this.getName() } override string explain() { result = this.getName() }
@@ -318,7 +318,7 @@ class BuiltInType extends Type, @builtintype {
*/ */
class ErroneousType extends BuiltInType { class ErroneousType extends BuiltInType {
ErroneousType() { builtintypes(this,_,1,_,_,_) } ErroneousType() { builtintypes(unresolveElement(this),_,1,_,_,_) }
} }
@@ -327,7 +327,7 @@ class ErroneousType extends BuiltInType {
*/ */
class UnknownType extends BuiltInType { class UnknownType extends BuiltInType {
UnknownType() { builtintypes(this,_,2,_,_,_) } UnknownType() { builtintypes(unresolveElement(this),_,2,_,_,_) }
} }
@@ -342,7 +342,7 @@ private predicate isArithmeticType(@builtintype type, int kind) {
*/ */
class ArithmeticType extends BuiltInType { class ArithmeticType extends BuiltInType {
ArithmeticType() { ArithmeticType() {
isArithmeticType(this, _) isArithmeticType(unresolveElement(this), _)
} }
} }
@@ -357,14 +357,14 @@ class IntegralOrEnumType extends Type {
IntegralOrEnumType() { IntegralOrEnumType() {
// Integral type // Integral type
exists(int kind | exists(int kind |
isArithmeticType(this, kind) and isArithmeticType(unresolveElement(this), kind) and
(kind < 24 or kind = 33 or (35 <= kind and kind <= 37) or (kind < 24 or kind = 33 or (35 <= kind and kind <= 37) or
kind = 43 or kind = 44) kind = 43 or kind = 44)
) or ) or
// Enum type // Enum type
( (
usertypes(this, _, 4) or usertypes(unresolveElement(this), _, 4) or
usertypes(this, _, 13) usertypes(unresolveElement(this), _, 13)
) )
} }
} }
@@ -375,33 +375,33 @@ class IntegralOrEnumType extends Type {
class IntegralType extends ArithmeticType, IntegralOrEnumType { class IntegralType extends ArithmeticType, IntegralOrEnumType {
/** Holds if this integral type is signed. */ /** Holds if this integral type is signed. */
predicate isSigned() { predicate isSigned() {
builtintypes(this,_,_,_,-1,_) builtintypes(unresolveElement(this),_,_,_,-1,_)
} }
/** Holds if this integral type is unsigned. */ /** Holds if this integral type is unsigned. */
predicate isUnsigned() { predicate isUnsigned() {
builtintypes(this,_,_,_,1,_) builtintypes(unresolveElement(this),_,_,_,1,_)
} }
/** Holds if this integral type is explicitly signed. */ /** Holds if this integral type is explicitly signed. */
predicate isExplicitlySigned() { predicate isExplicitlySigned() {
builtintypes(this,_,7,_,_,_) or builtintypes(this,_,10,_,_,_) or builtintypes(this,_,13,_,_,_) or builtintypes(unresolveElement(this),_,7,_,_,_) or builtintypes(unresolveElement(this),_,10,_,_,_) or builtintypes(unresolveElement(this),_,13,_,_,_) or
builtintypes(this,_,16,_,_,_) or builtintypes(this,_,19,_,_,_) or builtintypes(unresolveElement(this),_,16,_,_,_) or builtintypes(unresolveElement(this),_,19,_,_,_) or
builtintypes(this,_,37,_,_,_) builtintypes(unresolveElement(this),_,37,_,_,_)
} }
/** Holds if this integral type is explicitly unsigned. */ /** Holds if this integral type is explicitly unsigned. */
predicate isExplicitlyUnsigned() { predicate isExplicitlyUnsigned() {
builtintypes(this,_,6,_,_,_) or builtintypes(this,_,9,_,_,_) or builtintypes(this,_,12,_,_,_) or builtintypes(unresolveElement(this),_,6,_,_,_) or builtintypes(unresolveElement(this),_,9,_,_,_) or builtintypes(unresolveElement(this),_,12,_,_,_) or
builtintypes(this,_,15,_,_,_) or builtintypes(this,_,18,_,_,_) or builtintypes(unresolveElement(this),_,15,_,_,_) or builtintypes(unresolveElement(this),_,18,_,_,_) or
builtintypes(this,_,36,_,_,_) builtintypes(unresolveElement(this),_,36,_,_,_)
} }
/** Holds if this integral type is implicitly signed. */ /** Holds if this integral type is implicitly signed. */
predicate isImplicitlySigned() { predicate isImplicitlySigned() {
builtintypes(this,_,5,_,-1,_) or builtintypes(this,_,8,_,-1,_) or builtintypes(this,_,11,_,-1,_) or builtintypes(unresolveElement(this),_,5,_,-1,_) or builtintypes(unresolveElement(this),_,8,_,-1,_) or builtintypes(unresolveElement(this),_,11,_,-1,_) or
builtintypes(this,_,14,_,-1,_) or builtintypes(this,_,17,_,-1,_) or builtintypes(unresolveElement(this),_,14,_,-1,_) or builtintypes(unresolveElement(this),_,17,_,-1,_) or
builtintypes(this,_,35,_,-1,_) builtintypes(unresolveElement(this),_,35,_,-1,_)
} }
/** /**
@@ -409,12 +409,12 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
* example on a `short`, this would give the type `unsigned short`. * example on a `short`, this would give the type `unsigned short`.
*/ */
IntegralType getUnsigned() { IntegralType getUnsigned() {
(builtintypes(this,_, 5,_,_,_) or builtintypes(this,_, 6,_,_,_) or builtintypes(this,_, 7,_,_,_)) and builtintypes(result,_, 6,_,_,_) (builtintypes(unresolveElement(this),_, 5,_,_,_) or builtintypes(unresolveElement(this),_, 6,_,_,_) or builtintypes(unresolveElement(this),_, 7,_,_,_)) and builtintypes(unresolveElement(result),_, 6,_,_,_)
or (builtintypes(this,_, 8,_,_,_) or builtintypes(this,_, 9,_,_,_) or builtintypes(this,_,10,_,_,_)) and builtintypes(result,_, 9,_,_,_) or (builtintypes(unresolveElement(this),_, 8,_,_,_) or builtintypes(unresolveElement(this),_, 9,_,_,_) or builtintypes(unresolveElement(this),_,10,_,_,_)) and builtintypes(unresolveElement(result),_, 9,_,_,_)
or (builtintypes(this,_,11,_,_,_) or builtintypes(this,_,12,_,_,_) or builtintypes(this,_,13,_,_,_)) and builtintypes(result,_,12,_,_,_) or (builtintypes(unresolveElement(this),_,11,_,_,_) or builtintypes(unresolveElement(this),_,12,_,_,_) or builtintypes(unresolveElement(this),_,13,_,_,_)) and builtintypes(unresolveElement(result),_,12,_,_,_)
or (builtintypes(this,_,14,_,_,_) or builtintypes(this,_,15,_,_,_) or builtintypes(this,_,16,_,_,_)) and builtintypes(result,_,15,_,_,_) or (builtintypes(unresolveElement(this),_,14,_,_,_) or builtintypes(unresolveElement(this),_,15,_,_,_) or builtintypes(unresolveElement(this),_,16,_,_,_)) and builtintypes(unresolveElement(result),_,15,_,_,_)
or (builtintypes(this,_,17,_,_,_) or builtintypes(this,_,18,_,_,_) or builtintypes(this,_,19,_,_,_)) and builtintypes(result,_,18,_,_,_) or (builtintypes(unresolveElement(this),_,17,_,_,_) or builtintypes(unresolveElement(this),_,18,_,_,_) or builtintypes(unresolveElement(this),_,19,_,_,_)) and builtintypes(unresolveElement(result),_,18,_,_,_)
or (builtintypes(this,_,35,_,_,_) or builtintypes(this,_,36,_,_,_) or builtintypes(this,_,37,_,_,_)) and builtintypes(result,_,36,_,_,_) or (builtintypes(unresolveElement(this),_,35,_,_,_) or builtintypes(unresolveElement(this),_,36,_,_,_) or builtintypes(unresolveElement(this),_,37,_,_,_)) and builtintypes(unresolveElement(result),_,36,_,_,_)
} }
} }
@@ -423,7 +423,7 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
*/ */
class BoolType extends IntegralType { class BoolType extends IntegralType {
BoolType() { builtintypes(this,_,4,_,_,_) } BoolType() { builtintypes(unresolveElement(this),_,4,_,_,_) }
} }
@@ -437,7 +437,7 @@ abstract class CharType extends IntegralType { }
*/ */
class PlainCharType extends CharType { class PlainCharType extends CharType {
PlainCharType() { PlainCharType() {
builtintypes(this,_,5,_,_,_) builtintypes(unresolveElement(this),_,5,_,_,_)
} }
} }
@@ -446,7 +446,7 @@ class PlainCharType extends CharType {
*/ */
class UnsignedCharType extends CharType { class UnsignedCharType extends CharType {
UnsignedCharType() { UnsignedCharType() {
builtintypes(this,_,6,_,_,_) builtintypes(unresolveElement(this),_,6,_,_,_)
} }
} }
@@ -455,7 +455,7 @@ class UnsignedCharType extends CharType {
*/ */
class SignedCharType extends CharType { class SignedCharType extends CharType {
SignedCharType() { SignedCharType() {
builtintypes(this,_,7,_,_,_) builtintypes(unresolveElement(this),_,7,_,_,_)
} }
} }
@@ -465,7 +465,7 @@ class SignedCharType extends CharType {
class ShortType extends IntegralType { class ShortType extends IntegralType {
ShortType() { ShortType() {
builtintypes(this,_,8,_,_,_) or builtintypes(this,_,9,_,_,_) or builtintypes(this,_,10,_,_,_) builtintypes(unresolveElement(this),_,8,_,_,_) or builtintypes(unresolveElement(this),_,9,_,_,_) or builtintypes(unresolveElement(this),_,10,_,_,_)
} }
} }
@@ -476,7 +476,7 @@ class ShortType extends IntegralType {
class IntType extends IntegralType { class IntType extends IntegralType {
IntType() { IntType() {
builtintypes(this,_,11,_,_,_) or builtintypes(this,_,12,_,_,_) or builtintypes(this,_,13,_,_,_) builtintypes(unresolveElement(this),_,11,_,_,_) or builtintypes(unresolveElement(this),_,12,_,_,_) or builtintypes(unresolveElement(this),_,13,_,_,_)
} }
} }
@@ -487,7 +487,7 @@ class IntType extends IntegralType {
class LongType extends IntegralType { class LongType extends IntegralType {
LongType() { LongType() {
builtintypes(this,_,14,_,_,_) or builtintypes(this,_,15,_,_,_) or builtintypes(this,_,16,_,_,_) builtintypes(unresolveElement(this),_,14,_,_,_) or builtintypes(unresolveElement(this),_,15,_,_,_) or builtintypes(unresolveElement(this),_,16,_,_,_)
} }
} }
@@ -498,7 +498,7 @@ class LongType extends IntegralType {
class LongLongType extends IntegralType { class LongLongType extends IntegralType {
LongLongType() { LongLongType() {
builtintypes(this,_,17,_,_,_) or builtintypes(this,_,18,_,_,_) or builtintypes(this,_,19,_,_,_) builtintypes(unresolveElement(this),_,17,_,_,_) or builtintypes(unresolveElement(this),_,18,_,_,_) or builtintypes(unresolveElement(this),_,19,_,_,_)
} }
} }
@@ -509,7 +509,7 @@ class LongLongType extends IntegralType {
class Int128Type extends IntegralType { class Int128Type extends IntegralType {
Int128Type() { Int128Type() {
builtintypes(this,_,35,_,_,_) or builtintypes(this,_,36,_,_,_) or builtintypes(this,_,37,_,_,_) builtintypes(unresolveElement(this),_,35,_,_,_) or builtintypes(unresolveElement(this),_,36,_,_,_) or builtintypes(unresolveElement(this),_,37,_,_,_)
} }
} }
@@ -520,7 +520,7 @@ class Int128Type extends IntegralType {
class FloatingPointType extends ArithmeticType { class FloatingPointType extends ArithmeticType {
FloatingPointType() { FloatingPointType() {
exists(int kind | builtintypes(this,_,kind,_,_,_) and ((kind >= 24 and kind <= 32) or (kind = 38))) exists(int kind | builtintypes(unresolveElement(this),_,kind,_,_,_) and ((kind >= 24 and kind <= 32) or (kind = 38)))
} }
} }
@@ -530,7 +530,7 @@ class FloatingPointType extends ArithmeticType {
*/ */
class FloatType extends FloatingPointType { class FloatType extends FloatingPointType {
FloatType() { builtintypes(this,_,24,_,_,_) } FloatType() { builtintypes(unresolveElement(this),_,24,_,_,_) }
} }
@@ -539,7 +539,7 @@ class FloatType extends FloatingPointType {
*/ */
class DoubleType extends FloatingPointType { class DoubleType extends FloatingPointType {
DoubleType() { builtintypes(this,_,25,_,_,_) } DoubleType() { builtintypes(unresolveElement(this),_,25,_,_,_) }
} }
@@ -548,7 +548,7 @@ class DoubleType extends FloatingPointType {
*/ */
class LongDoubleType extends FloatingPointType { class LongDoubleType extends FloatingPointType {
LongDoubleType() { builtintypes(this,_,26,_,_,_) } LongDoubleType() { builtintypes(unresolveElement(this),_,26,_,_,_) }
} }
@@ -557,7 +557,7 @@ class LongDoubleType extends FloatingPointType {
*/ */
class Float128Type extends FloatingPointType { class Float128Type extends FloatingPointType {
Float128Type() { builtintypes(this,_,38,_,_,_) } Float128Type() { builtintypes(unresolveElement(this),_,38,_,_,_) }
} }
@@ -566,7 +566,7 @@ class Float128Type extends FloatingPointType {
*/ */
class Decimal32Type extends FloatingPointType { class Decimal32Type extends FloatingPointType {
Decimal32Type() { builtintypes(this,_,40,_,_,_) } Decimal32Type() { builtintypes(unresolveElement(this),_,40,_,_,_) }
} }
@@ -575,7 +575,7 @@ class Decimal32Type extends FloatingPointType {
*/ */
class Decimal64Type extends FloatingPointType { class Decimal64Type extends FloatingPointType {
Decimal64Type() { builtintypes(this,_,41,_,_,_) } Decimal64Type() { builtintypes(unresolveElement(this),_,41,_,_,_) }
} }
@@ -584,7 +584,7 @@ class Decimal64Type extends FloatingPointType {
*/ */
class Decimal128Type extends FloatingPointType { class Decimal128Type extends FloatingPointType {
Decimal128Type() { builtintypes(this,_,42,_,_,_) } Decimal128Type() { builtintypes(unresolveElement(this),_,42,_,_,_) }
} }
@@ -593,7 +593,7 @@ class Decimal128Type extends FloatingPointType {
*/ */
class VoidType extends BuiltInType { class VoidType extends BuiltInType {
VoidType() { builtintypes(this,_,3,_,_,_) } VoidType() { builtintypes(unresolveElement(this),_,3,_,_,_) }
} }
@@ -602,7 +602,7 @@ class VoidType extends BuiltInType {
*/ */
class WideCharType extends IntegralType { class WideCharType extends IntegralType {
WideCharType() { builtintypes(this,_,33,_,_,_) } WideCharType() { builtintypes(unresolveElement(this),_,33,_,_,_) }
} }
@@ -611,7 +611,7 @@ class WideCharType extends IntegralType {
*/ */
class Char16Type extends IntegralType { class Char16Type extends IntegralType {
Char16Type() { builtintypes(this,_,43,_,_,_) } Char16Type() { builtintypes(unresolveElement(this),_,43,_,_,_) }
} }
@@ -620,7 +620,7 @@ class Char16Type extends IntegralType {
*/ */
class Char32Type extends IntegralType { class Char32Type extends IntegralType {
Char32Type() { builtintypes(this,_,44,_,_,_) } Char32Type() { builtintypes(unresolveElement(this),_,44,_,_,_) }
} }
@@ -634,7 +634,7 @@ class Char32Type extends IntegralType {
* Instead, this is the unspeakable type given by `decltype(nullptr)`. * Instead, this is the unspeakable type given by `decltype(nullptr)`.
*/ */
class NullPointerType extends BuiltInType { class NullPointerType extends BuiltInType {
NullPointerType() { builtintypes(this,_,34,_,_,_) } NullPointerType() { builtintypes(unresolveElement(this),_,34,_,_,_) }
} }
/** /**
@@ -646,7 +646,7 @@ class NullPointerType extends BuiltInType {
class DerivedType extends Type, @derivedtype { class DerivedType extends Type, @derivedtype {
override string toString() { result = this.getName() } override string toString() { result = this.getName() }
override string getName() { derivedtypes(this,result,_,_) } override string getName() { derivedtypes(unresolveElement(this),result,_,_) }
/** /**
* Gets the base type of this derived type. * Gets the base type of this derived type.
@@ -654,7 +654,7 @@ class DerivedType extends Type, @derivedtype {
* This predicate strips off one level of decoration from a type. For example, it returns `char*` for the PointerType `char**`, * This predicate strips off one level of decoration from a type. For example, it returns `char*` for the PointerType `char**`,
* `const int` for the ReferenceType `const int&amp;`, and `long` for the SpecifiedType `volatile long`. * `const int` for the ReferenceType `const int&amp;`, and `long` for the SpecifiedType `volatile long`.
*/ */
Type getBaseType() { derivedtypes(this,_,_,unresolve(result)) } Type getBaseType() { derivedtypes(unresolveElement(this),_,_,unresolveElement(result)) }
override predicate refersToDirectly(Type t) { t = this.getBaseType() } override predicate refersToDirectly(Type t) { t = this.getBaseType() }
@@ -700,14 +700,14 @@ class Decltype extends Type, @decltype {
* The expression whose type is being obtained by this decltype. * The expression whose type is being obtained by this decltype.
*/ */
Expr getExpr() { Expr getExpr() {
decltypes(this, result, _, _) decltypes(unresolveElement(this), unresolveElement(result), _, _)
} }
/** /**
* The type immediately yielded by this decltype. * The type immediately yielded by this decltype.
*/ */
Type getBaseType() { Type getBaseType() {
decltypes(this, _, unresolve(result), _) decltypes(unresolveElement(this), _, unresolveElement(result), _)
} }
/** /**
@@ -721,7 +721,7 @@ class Decltype extends Type, @decltype {
* Consult the C++11 standard for more details. * Consult the C++11 standard for more details.
*/ */
predicate parenthesesWouldChangeMeaning() { predicate parenthesesWouldChangeMeaning() {
decltypes(this, _, _, true) decltypes(unresolveElement(this), _, _, true)
} }
override Type getUnderlyingType() { override Type getUnderlyingType() {
@@ -794,7 +794,7 @@ class Decltype extends Type, @decltype {
*/ */
class PointerType extends DerivedType { class PointerType extends DerivedType {
PointerType() { derivedtypes(this,_,1,_) } PointerType() { derivedtypes(unresolveElement(this),_,1,_) }
override int getPointerIndirectionLevel() { override int getPointerIndirectionLevel() {
result = 1 + this.getBaseType().getPointerIndirectionLevel() result = 1 + this.getBaseType().getPointerIndirectionLevel()
@@ -817,7 +817,7 @@ class PointerType extends DerivedType {
*/ */
class ReferenceType extends DerivedType { class ReferenceType extends DerivedType {
ReferenceType() { derivedtypes(this,_,2,_) or derivedtypes(this,_,8,_) } ReferenceType() { derivedtypes(unresolveElement(this),_,2,_) or derivedtypes(unresolveElement(this),_,8,_) }
override int getPointerIndirectionLevel() { override int getPointerIndirectionLevel() {
result = getBaseType().getPointerIndirectionLevel() result = getBaseType().getPointerIndirectionLevel()
@@ -842,14 +842,14 @@ class ReferenceType extends DerivedType {
* A C++11 lvalue reference type (e.g. int&amp;). * A C++11 lvalue reference type (e.g. int&amp;).
*/ */
class LValueReferenceType extends ReferenceType { class LValueReferenceType extends ReferenceType {
LValueReferenceType() { derivedtypes(this,_,2,_) } LValueReferenceType() { derivedtypes(unresolveElement(this),_,2,_) }
} }
/** /**
* A C++11 rvalue reference type (e.g. int&amp;&amp;). * A C++11 rvalue reference type (e.g. int&amp;&amp;).
*/ */
class RValueReferenceType extends ReferenceType { class RValueReferenceType extends ReferenceType {
RValueReferenceType() { derivedtypes(this,_,8,_) } RValueReferenceType() { derivedtypes(unresolveElement(this),_,8,_) }
override string explain() { result = "rvalue " + super.explain() } override string explain() { result = "rvalue " + super.explain() }
} }
@@ -859,7 +859,7 @@ class RValueReferenceType extends ReferenceType {
*/ */
class SpecifiedType extends DerivedType { class SpecifiedType extends DerivedType {
SpecifiedType() { derivedtypes(this,_,3,_) } SpecifiedType() { derivedtypes(unresolveElement(this),_,3,_) }
override int getSize() { result = this.getBaseType().getSize() } override int getSize() { result = this.getBaseType().getSize() }
@@ -901,14 +901,14 @@ class SpecifiedType extends DerivedType {
*/ */
class ArrayType extends DerivedType { class ArrayType extends DerivedType {
ArrayType() { derivedtypes(this,_,4,_) } ArrayType() { derivedtypes(unresolveElement(this),_,4,_) }
predicate hasArraySize() { arraysizes(this,_,_,_) } predicate hasArraySize() { arraysizes(unresolveElement(this),_,_,_) }
int getArraySize() { arraysizes(this,result,_,_) } int getArraySize() { arraysizes(unresolveElement(this),result,_,_) }
int getByteSize() { arraysizes(this,_,result,_) } int getByteSize() { arraysizes(unresolveElement(this),_,result,_) }
override int getAlignment() { arraysizes(this, _, _, result) } override int getAlignment() { arraysizes(unresolveElement(this), _, _, result) }
/** /**
* Gets the size of this array (only valid for arrays declared to be of a constant * Gets the size of this array (only valid for arrays declared to be of a constant
@@ -941,7 +941,7 @@ class ArrayType extends DerivedType {
*/ */
class GNUVectorType extends DerivedType { class GNUVectorType extends DerivedType {
GNUVectorType() { derivedtypes(this,_,5,_) } GNUVectorType() { derivedtypes(unresolveElement(this),_,5,_) }
/** /**
* Get the number of elements in this vector type. * Get the number of elements in this vector type.
@@ -952,7 +952,7 @@ class GNUVectorType extends DerivedType {
* the number of elements is the value in the attribute divided by the size * the number of elements is the value in the attribute divided by the size
* of a single element. * of a single element.
*/ */
int getNumElements() { arraysizes(this,result,_,_) } int getNumElements() { arraysizes(unresolveElement(this),result,_,_) }
/** /**
* Gets the size, in bytes, of this vector type. * Gets the size, in bytes, of this vector type.
@@ -963,9 +963,9 @@ class GNUVectorType extends DerivedType {
* attribute, the byte size is the value in the attribute multiplied by the * attribute, the byte size is the value in the attribute multiplied by the
* byte size of a single element. * byte size of a single element.
*/ */
override int getSize() { arraysizes(this,_,result,_) } override int getSize() { arraysizes(unresolveElement(this),_,result,_) }
override int getAlignment() { arraysizes(this, _, _, result) } override int getAlignment() { arraysizes(unresolveElement(this), _, _, result) }
override string explain() { result = "GNU " + getNumElements() + " element vector of {" + this.getBaseType().explain() + "}" } override string explain() { result = "GNU " + getNumElements() + " element vector of {" + this.getBaseType().explain() + "}" }
@@ -978,7 +978,7 @@ class GNUVectorType extends DerivedType {
*/ */
class FunctionPointerType extends FunctionPointerIshType { class FunctionPointerType extends FunctionPointerIshType {
FunctionPointerType() { FunctionPointerType() {
derivedtypes(this,_,6,_) derivedtypes(unresolveElement(this),_,6,_)
} }
override int getPointerIndirectionLevel() { override int getPointerIndirectionLevel() {
@@ -993,7 +993,7 @@ class FunctionPointerType extends FunctionPointerIshType {
*/ */
class FunctionReferenceType extends FunctionPointerIshType { class FunctionReferenceType extends FunctionPointerIshType {
FunctionReferenceType() { FunctionReferenceType() {
derivedtypes(this,_,7,_) derivedtypes(unresolveElement(this),_,7,_)
} }
override int getPointerIndirectionLevel() { override int getPointerIndirectionLevel() {
@@ -1011,7 +1011,7 @@ class FunctionReferenceType extends FunctionPointerIshType {
*/ */
class BlockType extends FunctionPointerIshType { class BlockType extends FunctionPointerIshType {
BlockType() { BlockType() {
derivedtypes(this,_,10,_) derivedtypes(unresolveElement(this),_,10,_)
} }
override int getPointerIndirectionLevel() { override int getPointerIndirectionLevel() {
@@ -1026,24 +1026,24 @@ class BlockType extends FunctionPointerIshType {
*/ */
class FunctionPointerIshType extends DerivedType { class FunctionPointerIshType extends DerivedType {
FunctionPointerIshType() { FunctionPointerIshType() {
derivedtypes(this,_,6, _) or derivedtypes(unresolveElement(this),_,6, _) or
derivedtypes(this,_,7, _) or derivedtypes(unresolveElement(this),_,7, _) or
derivedtypes(this,_,10,_) derivedtypes(unresolveElement(this),_,10,_)
} }
/** the return type of this function pointer type */ /** the return type of this function pointer type */
Type getReturnType() { Type getReturnType() {
exists(RoutineType t | derivedtypes(this,_,_,t) and result = t.getReturnType()) exists(RoutineType t | derivedtypes(unresolveElement(this),_,_,unresolveElement(t)) and result = t.getReturnType())
} }
/** the type of the ith argument of this function pointer type */ /** the type of the ith argument of this function pointer type */
Type getParameterType(int i) { Type getParameterType(int i) {
exists(RoutineType t | derivedtypes(this,_,_,t) and result = t.getParameterType(i)) exists(RoutineType t | derivedtypes(unresolveElement(this),_,_,unresolveElement(t)) and result = t.getParameterType(i))
} }
/** the type of an argument of this function pointer type */ /** the type of an argument of this function pointer type */
Type getAParameterType() { Type getAParameterType() {
exists(RoutineType t | derivedtypes(this,_,_,t) and result = t.getAParameterType()) exists(RoutineType t | derivedtypes(unresolveElement(this),_,_,unresolveElement(t)) and result = t.getAParameterType())
} }
/** the number of arguments of this function pointer type */ /** the number of arguments of this function pointer type */
@@ -1070,10 +1070,10 @@ class PointerToMemberType extends Type, @ptrtomember {
override string getName() { result = "..:: *" } override string getName() { result = "..:: *" }
/** the base type of this pointer to member type */ /** the base type of this pointer to member type */
Type getBaseType() { ptrtomembers(this,unresolve(result),_) } Type getBaseType() { ptrtomembers(unresolveElement(this),unresolveElement(result),_) }
/** the class referred by this pointer to member type */ /** the class referred by this pointer to member type */
Type getClass() { ptrtomembers(this,_,unresolve(result)) } Type getClass() { ptrtomembers(unresolveElement(this),_,unresolveElement(result)) }
override predicate refersToDirectly(Type t) { override predicate refersToDirectly(Type t) {
t = this.getBaseType() or t = this.getBaseType() or
@@ -1102,11 +1102,11 @@ class RoutineType extends Type, @routinetype {
override string getName() { result = "..()(..)" } override string getName() { result = "..()(..)" }
Type getParameterType(int n) { routinetypeargs(this,n,unresolve(result)) } Type getParameterType(int n) { routinetypeargs(unresolveElement(this),n,unresolveElement(result)) }
Type getAParameterType() { routinetypeargs(this,_,unresolve(result)) } Type getAParameterType() { routinetypeargs(unresolveElement(this),_,unresolveElement(result)) }
Type getReturnType() { routinetypes(this, unresolve(result)) } Type getReturnType() { routinetypes(unresolveElement(this), unresolveElement(result)) }
override string explain() { override string explain() {
result = "function returning {" + this.getReturnType().explain() + result = "function returning {" + this.getReturnType().explain() +
@@ -1153,9 +1153,9 @@ class RoutineType extends Type, @routinetype {
*/ */
class TemplateParameter extends UserType class TemplateParameter extends UserType
{ {
TemplateParameter() { usertypes(this, _, 7) or usertypes(this, _, 8) } TemplateParameter() { usertypes(unresolveElement(this), _, 7) or usertypes(unresolveElement(this), _, 8) }
override string getName() { usertypes(this, result, _) } override string getName() { usertypes(unresolveElement(this), result, _) }
override predicate involvesTemplateParameter() { override predicate involvesTemplateParameter() {
any() any()
@@ -1166,7 +1166,7 @@ class TemplateParameter extends UserType
class TemplateTemplateParameter extends TemplateParameter class TemplateTemplateParameter extends TemplateParameter
{ {
TemplateTemplateParameter() { TemplateTemplateParameter() {
usertypes(this, _, 8) usertypes(unresolveElement(this), _, 8)
} }
} }
@@ -1175,7 +1175,7 @@ class TemplateTemplateParameter extends TemplateParameter
*/ */
class AutoType extends TemplateParameter class AutoType extends TemplateParameter
{ {
AutoType() { usertypes(this, "auto", 7) } AutoType() { usertypes(unresolveElement(this), "auto", 7) }
override Location getLocation() { override Location getLocation() {
suppressUnusedThis(this) and suppressUnusedThis(this) and
@@ -1209,8 +1209,8 @@ class TypeMention extends Locatable, @type_mention {
/** /**
* Gets the type being referenced by this type mention. * Gets the type being referenced by this type mention.
*/ */
Type getMentionedType() { type_mentions(this, result, _, _) } Type getMentionedType() { type_mentions(unresolveElement(this), unresolveElement(result), _, _) }
override Location getLocation() { type_mentions(this, _, result, _)} override Location getLocation() { type_mentions(unresolveElement(this), _, result, _)}
} }

View File

@@ -6,12 +6,12 @@ private import semmle.code.cpp.internal.Type
*/ */
class TypedefType extends UserType { class TypedefType extends UserType {
TypedefType() { usertypes(this,_,5) } TypedefType() { usertypes(unresolveElement(this),_,5) }
/** /**
* Gets the base type of this typedef type. * Gets the base type of this typedef type.
*/ */
Type getBaseType() { typedefbase(this,unresolve(result)) } Type getBaseType() { typedefbase(unresolveElement(this),unresolveElement(result)) }
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() } override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }

View File

@@ -6,7 +6,7 @@ import semmle.code.cpp.Struct
*/ */
class Union extends Struct { class Union extends Struct {
Union() { usertypes(this,_,3) } Union() { usertypes(unresolveElement(this),_,3) }
override string explain() { result = "union " + this.getName() } override string explain() { result = "union " + this.getName() }

View File

@@ -9,12 +9,8 @@ private import semmle.code.cpp.internal.Type
* `Enum`, and `TypedefType`. * `Enum`, and `TypedefType`.
*/ */
class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @usertype { class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @usertype {
UserType() {
isClass(this) implies this = resolve(_)
}
/** the name of this type */ /** the name of this type */
override string getName() { usertypes(this,result,_) } override string getName() { usertypes(unresolveElement(this),result,_) }
/** the simple name of this type, without any template parameters */ /** the simple name of this type, without any template parameters */
string getSimpleName() { string getSimpleName() {
@@ -22,7 +18,7 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
} }
override predicate hasName(string name) { override predicate hasName(string name) {
usertypes(this,name,_) usertypes(unresolveElement(this),name,_)
} }
predicate isAnonymous() { predicate isAnonymous() {
getName().matches("(unnamed%") getName().matches("(unnamed%")
@@ -43,8 +39,8 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
} }
override TypeDeclarationEntry getADeclarationEntry() { override TypeDeclarationEntry getADeclarationEntry() {
if type_decls(_, unresolve(this), _) then if type_decls(_, unresolveElement(this), _) then
type_decls(result, unresolve(this), _) type_decls(unresolveElement(result), unresolveElement(this), _)
else else
exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry()) exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
} }
@@ -68,7 +64,7 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
/** Gets the function that directly encloses this type (if any). */ /** Gets the function that directly encloses this type (if any). */
Function getEnclosingFunction() { Function getEnclosingFunction() {
enclosingfunction(this,result) enclosingfunction(unresolveElement(this),unresolveElement(result))
} }
/** Whether this is a local type (i.e. a type that has a directly-enclosing function). */ /** Whether this is a local type (i.e. a type that has a directly-enclosing function). */
@@ -100,15 +96,15 @@ class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
/** /**
* The type which is being declared or defined. * The type which is being declared or defined.
*/ */
override Type getType() { type_decls(this,unresolve(result),_) } override Type getType() { type_decls(unresolveElement(this),unresolveElement(result),_) }
override Location getLocation() { type_decls(this,_,result) } override Location getLocation() { type_decls(unresolveElement(this),_,result) }
override predicate isDefinition() { type_def(this) } override predicate isDefinition() { type_def(unresolveElement(this)) }
override string getASpecifier() { none() } override string getASpecifier() { none() }
/** /**
* A top level type declaration entry is not declared within a function, function declaration, * A top level type declaration entry is not declared within a function, function declaration,
* class or typedef. * class or typedef.
*/ */
predicate isTopLevel() { type_decl_top(this) } predicate isTopLevel() { type_decl_top(unresolveElement(this)) }
} }

View File

@@ -30,10 +30,10 @@ class Variable extends Declaration, @variable {
* this variable, such as `const` and `volatile`, are instead accessed * this variable, such as `const` and `volatile`, are instead accessed
* through `this.getType().getASpecifier()`. * through `this.getType().getASpecifier()`.
*/ */
override Specifier getASpecifier() { varspecifiers(this,result) } override Specifier getASpecifier() { varspecifiers(unresolveElement(this),unresolveElement(result)) }
/** Gets an attribute of this variable. */ /** Gets an attribute of this variable. */
Attribute getAnAttribute() { varattributes(this,result) } Attribute getAnAttribute() { varattributes(unresolveElement(this),unresolveElement(result)) }
/** Holds if this variable is `const`. */ /** Holds if this variable is `const`. */
predicate isConst() { this.getType().isConst() } predicate isConst() { this.getType().isConst() }
@@ -67,13 +67,13 @@ class Variable extends Declaration, @variable {
* *
* `const auto& c = container;` * `const auto& c = container;`
*/ */
Type getTypeWithAuto() { autoderivation(this, unresolve(result)) } Type getTypeWithAuto() { autoderivation(unresolveElement(this), unresolveElement(result)) }
/** /**
* Holds if the type of this variable is declared using the C++ `auto` * Holds if the type of this variable is declared using the C++ `auto`
* keyword. * keyword.
*/ */
predicate declaredUsingAutoType() { autoderivation(this, _) } predicate declaredUsingAutoType() { autoderivation(unresolveElement(this), _) }
override VariableDeclarationEntry getADeclarationEntry() { override VariableDeclarationEntry getADeclarationEntry() {
result.getDeclaration() = this result.getDeclaration() = this
@@ -127,7 +127,7 @@ class Variable extends Declaration, @variable {
* variable or from a variable nested in a template class. * variable or from a variable nested in a template class.
*/ */
predicate isConstructedFrom(Variable v) { predicate isConstructedFrom(Variable v) {
variable_instantiation(this, v) variable_instantiation(unresolveElement(this), unresolveElement(v))
} }
/** /**
@@ -143,7 +143,7 @@ class Variable extends Declaration, @variable {
* template variable. * template variable.
*/ */
Type getTemplateArgument(int index) { Type getTemplateArgument(int index) {
variable_template_argument(this, index, unresolve(result)) variable_template_argument(unresolveElement(this), index, unresolveElement(result))
} }
/** /**
@@ -154,7 +154,7 @@ class Variable extends Declaration, @variable {
* *
* `for (char c : str) { ... }` * `for (char c : str) { ... }`
*/ */
predicate isCompilerGenerated() { compgenerated(this) } predicate isCompilerGenerated() { compgenerated(unresolveElement(this)) }
} }
/** /**
@@ -166,7 +166,7 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
/** /**
* Gets the variable which is being declared or defined. * Gets the variable which is being declared or defined.
*/ */
Variable getVariable() { var_decls(this,result,_,_,_) } Variable getVariable() { var_decls(unresolveElement(this),unresolveElement(result),_,_,_) }
/** /**
* Gets the name, if any, used for the variable at this declaration or * Gets the name, if any, used for the variable at this declaration or
@@ -185,14 +185,14 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
* int f(int y) { return y; } * int f(int y) { return y; }
* ``` * ```
*/ */
override string getName() { var_decls(this,_,_,result,_) and result != "" } override string getName() { var_decls(unresolveElement(this),_,_,result,_) and result != "" }
/** /**
* Gets the type of the variable which is being declared or defined. * Gets the type of the variable which is being declared or defined.
*/ */
override Type getType() { var_decls(this,_,unresolve(result),_,_) } override Type getType() { var_decls(unresolveElement(this),_,unresolveElement(result),_,_) }
override Location getLocation() { var_decls(this,_,_,_,result) } override Location getLocation() { var_decls(unresolveElement(this),_,_,_,result) }
/** /**
* Holds if this is a definition of a variable. * Holds if this is a definition of a variable.
@@ -202,9 +202,9 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
* this holds precisely when the enclosing `FunctionDeclarationEntry` is * this holds precisely when the enclosing `FunctionDeclarationEntry` is
* a definition. * a definition.
*/ */
override predicate isDefinition() { var_def(this) } override predicate isDefinition() { var_def(unresolveElement(this)) }
override string getASpecifier() { var_decl_specifiers(this,result) } override string getASpecifier() { var_decl_specifiers(unresolveElement(this),result) }
} }
/** /**
@@ -212,20 +212,20 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
* of a C/C++ function. * of a C/C++ function.
*/ */
class ParameterDeclarationEntry extends VariableDeclarationEntry { class ParameterDeclarationEntry extends VariableDeclarationEntry {
ParameterDeclarationEntry() { param_decl_bind(this,_,_) } ParameterDeclarationEntry() { param_decl_bind(unresolveElement(this),_,_) }
/** /**
* Gets the function declaration or definition which this parameter * Gets the function declaration or definition which this parameter
* description is part of. * description is part of.
*/ */
FunctionDeclarationEntry getFunctionDeclarationEntry() { FunctionDeclarationEntry getFunctionDeclarationEntry() {
param_decl_bind(this,_,result) param_decl_bind(unresolveElement(this),_,unresolveElement(result))
} }
/** /**
* Gets the zero-based index of this parameter. * Gets the zero-based index of this parameter.
*/ */
int getIndex() { param_decl_bind(this,result,_) } int getIndex() { param_decl_bind(unresolveElement(this),result,_) }
override string toString() { override string toString() {
if exists(getName()) if exists(getName())
@@ -286,9 +286,9 @@ deprecated class StackVariable extends Variable {
* scope [N4140 3.3.3], but is not a function parameter. * scope [N4140 3.3.3], but is not a function parameter.
*/ */
class LocalVariable extends LocalScopeVariable, @localvariable { class LocalVariable extends LocalScopeVariable, @localvariable {
override string getName() { localvariables(this,_,result) } override string getName() { localvariables(unresolveElement(this),_,result) }
override Type getType() { localvariables(this,unresolve(result),_) } override Type getType() { localvariables(unresolveElement(this),unresolveElement(result),_) }
override Function getFunction() { override Function getFunction() {
exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result) exists(DeclStmt s | s.getADeclaration() = this and s.getEnclosingFunction() = result)
@@ -299,9 +299,9 @@ class LocalVariable extends LocalScopeVariable, @localvariable {
* A C/C++ variable which has global scope or namespace scope. * A C/C++ variable which has global scope or namespace scope.
*/ */
class GlobalOrNamespaceVariable extends Variable, @globalvariable { class GlobalOrNamespaceVariable extends Variable, @globalvariable {
override string getName() { globalvariables(this,_,result) } override string getName() { globalvariables(unresolveElement(this),_,result) }
override Type getType() { globalvariables(this,unresolve(result),_) } override Type getType() { globalvariables(unresolveElement(this),unresolveElement(result),_) }
override Element getEnclosingElement() { none() } override Element getEnclosingElement() { none() }
} }
@@ -311,7 +311,7 @@ class GlobalOrNamespaceVariable extends Variable, @globalvariable {
*/ */
class NamespaceVariable extends GlobalOrNamespaceVariable { class NamespaceVariable extends GlobalOrNamespaceVariable {
NamespaceVariable() { NamespaceVariable() {
exists(Namespace n | namespacembrs(n, this)) exists(Namespace n | namespacembrs(unresolveElement(n), unresolveElement(this)))
} }
} }
@@ -348,7 +348,7 @@ class MemberVariable extends Variable, @membervariable {
/** Holds if this member is public. */ /** Holds if this member is public. */
predicate isPublic() { this.hasSpecifier("public") } predicate isPublic() { this.hasSpecifier("public") }
override string getName() { membervariables(this,_,result) } override string getName() { membervariables(unresolveElement(this),_,result) }
override Type getType() { override Type getType() {
if (strictcount(this.getAType()) = 1) then ( if (strictcount(this.getAType()) = 1) then (
@@ -366,7 +366,7 @@ class MemberVariable extends Variable, @membervariable {
getADeclarationEntry().hasSpecifier("mutable") getADeclarationEntry().hasSpecifier("mutable")
} }
private Type getAType() { membervariables(this,unresolve(result),_) } private Type getAType() { membervariables(unresolveElement(this),unresolveElement(result),_) }
} }
/** /**
@@ -391,7 +391,7 @@ class FunctionPointerMemberVariable extends MemberVariable {
* A C++14 variable template. * A C++14 variable template.
*/ */
class TemplateVariable extends Variable { class TemplateVariable extends Variable {
TemplateVariable() { is_variable_template(this) } TemplateVariable() { is_variable_template(unresolveElement(this)) }
Variable getAnInstantiation() { result.isConstructedFrom(this) } Variable getAnInstantiation() { result.isConstructedFrom(this) }
} }

View File

@@ -15,7 +15,7 @@ abstract class XMLLocatable extends @xmllocatable {
*/ */
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) { predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
exists(File f, Location l | l = this.getLocation() | exists(File f, Location l | l = this.getLocation() |
locations_default(l,f,startline,startcolumn,endline,endcolumn) and locations_default(l,unresolveElement(f),startline,startcolumn,endline,endcolumn) and
filepath = f.getAbsolutePath() filepath = f.getAbsolutePath()
) )
} }
@@ -94,7 +94,7 @@ class XMLParent extends @xmlparent {
} }
/** An XML file. */ /** An XML file. */
class XMLFile extends XMLParent, File { class XMLFile extends XMLParent {
XMLFile() { XMLFile() {
xmlEncoding(this,_) xmlEncoding(this,_)
} }

View File

@@ -345,7 +345,7 @@ private predicate dependsOnFull(DependsSource src, Symbol dest, int category) {
*/ */
private private
predicate dependency_functionUse(Element src, Function dest) { predicate dependency_functionUse(Element src, Function dest) {
funbind(src, dest) funbind(unresolveElement(src), unresolveElement(dest))
} }
/** /**
@@ -407,7 +407,7 @@ Type typeUsedBy(Element src) {
) or ( ) or (
result = src.(SizeofTypeOperator).getTypeOperand() result = src.(SizeofTypeOperator).getTypeOperand()
) or exists(Function f | ) or exists(Function f |
funbind(src, f) and result = f.getATemplateArgument() funbind(unresolveElement(src), unresolveElement(f)) and result = f.getATemplateArgument()
) or ( ) or (
result = src.(NewExpr).getType() and not result.(Class).hasConstructor() result = src.(NewExpr).getType() and not result.(Class).hasConstructor()
) or ( ) or (

View File

@@ -60,7 +60,7 @@ private cached module Cached {
private predicate non_primitive_basic_block_entry_node(ControlFlowNode node) { private predicate non_primitive_basic_block_entry_node(ControlFlowNode node) {
not primitive_basic_block_entry_node(node) and not primitive_basic_block_entry_node(node) and
not exists(node.getAPredecessor()) and not exists(node.getAPredecessor()) and
successors_extended(node, _) successors_extended(unresolveElement(node), _)
} }
/** /**
@@ -80,7 +80,7 @@ private cached module Cached {
* reuse predicates already computed for `PrimitiveBasicBlocks`. * reuse predicates already computed for `PrimitiveBasicBlocks`.
*/ */
private predicate equalsPrimitiveBasicBlock(BasicBlock bb) { private predicate equalsPrimitiveBasicBlock(BasicBlock bb) {
primitive_basic_block_entry_node(bb) primitive_basic_block_entry_node(mkElement(bb))
and and
not exists(int i | not exists(int i |
i > 0 and i > 0 and
@@ -96,11 +96,11 @@ private cached module Cached {
} }
private predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) { private predicate non_primitive_basic_block_member(ControlFlowNode node, BasicBlock bb, int pos) {
(not equalsPrimitiveBasicBlock(bb) and node = bb and pos = 0) (not equalsPrimitiveBasicBlock(bb) and node = mkElement(bb) and pos = 0)
or or
(not (node instanceof BasicBlock) and (not (unresolveElement(node) instanceof BasicBlock) and
exists (ControlFlowNode pred exists (ControlFlowNode pred
| successors_extended(pred,node) | successors_extended(unresolveElement(pred),unresolveElement(node))
| non_primitive_basic_block_member(pred, bb, pos - 1))) | non_primitive_basic_block_member(pred, bb, pos - 1)))
} }
@@ -117,7 +117,7 @@ private cached module Cached {
predicate bb_successor_cached(BasicBlock pred, BasicBlock succ) { predicate bb_successor_cached(BasicBlock pred, BasicBlock succ) {
exists(ControlFlowNode last | exists(ControlFlowNode last |
basic_block_member(last, pred, bb_length(pred)-1) and basic_block_member(last, pred, bb_length(pred)-1) and
last.getASuccessor() = succ last.getASuccessor() = mkElement(succ)
) )
} }
} }
@@ -146,7 +146,7 @@ predicate bb_successor = bb_successor_cached/2;
class BasicBlock extends @cfgnode { class BasicBlock extends @cfgnode {
BasicBlock() { BasicBlock() {
basic_block_entry_node(this) basic_block_entry_node(mkElement(this))
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
@@ -187,7 +187,7 @@ class BasicBlock extends @cfgnode {
} }
ControlFlowNode getStart() { ControlFlowNode getStart() {
result = this result = mkElement(this)
} }
/** Gets the number of `ControlFlowNode`s in this basic block. */ /** Gets the number of `ControlFlowNode`s in this basic block. */
@@ -248,9 +248,9 @@ class BasicBlock extends @cfgnode {
* point or a `catch` clause of a reachable `try` statement. * point or a `catch` clause of a reachable `try` statement.
*/ */
predicate isReachable() { predicate isReachable() {
exists(Function f | f.getBlock() = this) exists(Function f | f.getBlock() = mkElement(this))
or or
exists(TryStmt t, BasicBlock tryblock | this = t.getACatchClause() and tryblock.isReachable() and tryblock.contains(t)) exists(TryStmt t, BasicBlock tryblock | mkElement(this) = t.getACatchClause() and tryblock.isReachable() and tryblock.contains(t))
or or
exists(BasicBlock pred | pred.getASuccessor() = this and pred.isReachable()) exists(BasicBlock pred | pred.getASuccessor() = this and pred.isReachable())
} }
@@ -272,7 +272,7 @@ predicate unreachable(ControlFlowNode n) {
*/ */
class EntryBasicBlock extends BasicBlock { class EntryBasicBlock extends BasicBlock {
EntryBasicBlock() { EntryBasicBlock() {
exists (Function f | this = f.getEntryPoint()) exists (Function f | mkElement(this) = f.getEntryPoint())
} }
} }

View File

@@ -29,7 +29,7 @@ private import semmle.code.cpp.controlflow.internal.ConstantExprs
*/ */
class ControlFlowNode extends Locatable, @cfgnode { class ControlFlowNode extends Locatable, @cfgnode {
ControlFlowNode getASuccessor() { successors_adapted(this,result) } ControlFlowNode getASuccessor() { successors_adapted(unresolveElement(this),unresolveElement(result)) }
ControlFlowNode getAPredecessor() { this = result.getASuccessor() } ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
@@ -54,7 +54,7 @@ class ControlFlowNode extends Locatable, @cfgnode {
* taken when this expression is true. * taken when this expression is true.
*/ */
ControlFlowNode getATrueSuccessor() { ControlFlowNode getATrueSuccessor() {
truecond(this,result) and result = getASuccessor() truecond(unresolveElement(this),unresolveElement(result)) and result = getASuccessor()
} }
/** /**
@@ -62,7 +62,7 @@ class ControlFlowNode extends Locatable, @cfgnode {
* taken when this expression is false. * taken when this expression is false.
*/ */
ControlFlowNode getAFalseSuccessor() { ControlFlowNode getAFalseSuccessor() {
falsecond(this,result) and result = getASuccessor() falsecond(unresolveElement(this),unresolveElement(result)) and result = getASuccessor()
} }
BasicBlock getBasicBlock() { BasicBlock getBasicBlock() {
@@ -86,7 +86,7 @@ private cached module Cached {
exists(Function f | f.getEntryPoint() = n) exists(Function f | f.getEntryPoint() = n)
or or
// Okay to use successors_extended directly here // Okay to use successors_extended directly here
(not successors_extended(_,n) and not successors_extended(n,_)) (not successors_extended(_,unresolveElement(n)) and not successors_extended(unresolveElement(n),_))
or or
reachable(n.getAPredecessor()) reachable(n.getAPredecessor())
or or
@@ -158,7 +158,7 @@ abstract class AdditionalControlFlowEdge extends @cfgnode {
/** Gets a target node of this edge, where the source node is `this`. */ /** Gets a target node of this edge, where the source node is `this`. */
abstract ControlFlowNode getAnEdgeTarget(); abstract ControlFlowNode getAnEdgeTarget();
string toString() { result = this.(ControlFlowNode).toString() } string toString() { result = mkElement(this).(ControlFlowNode).toString() }
} }
/** /**
@@ -169,5 +169,5 @@ abstract class AdditionalControlFlowEdge extends @cfgnode {
predicate successors_extended(@cfgnode source, @cfgnode target) { predicate successors_extended(@cfgnode source, @cfgnode target) {
successors(source, target) successors(source, target)
or or
source.(AdditionalControlFlowEdge).getAnEdgeTarget() = target source.(AdditionalControlFlowEdge).getAnEdgeTarget() = mkElement(target)
} }

View File

@@ -11,9 +11,9 @@ private import semmle.code.cpp.dataflow.EscapesTree
*/ */
predicate definitionUsePair(SemanticStackVariable var, Expr def, Expr use) { predicate definitionUsePair(SemanticStackVariable var, Expr def, Expr use) {
exists(Use u | exists(Use u |
u = use mkElement(u) = use
and and
def.(Def).reaches(true, var, u) unresolveElement(def).(Def).reaches(true, var, u)
and and
u.getVariable(false) = var u.getVariable(false) = var
) )
@@ -24,7 +24,7 @@ predicate definitionUsePair(SemanticStackVariable var, Expr def, Expr use) {
* is a definition or use, without crossing definitions of the same variable. * is a definition or use, without crossing definitions of the same variable.
*/ */
predicate definitionReaches(Expr def, Expr node) { predicate definitionReaches(Expr def, Expr node) {
def.(Def).reaches(true, _, (DefOrUse)node) unresolveElement(def).(Def).reaches(true, _, (DefOrUse)unresolveElement(node))
} }
private predicate hasAddressOfAccess(SemanticStackVariable var) { private predicate hasAddressOfAccess(SemanticStackVariable var) {
@@ -61,9 +61,9 @@ predicate useUsePair(SemanticStackVariable var, Expr first, Expr second) {
not definition(var, first) not definition(var, first)
and and
exists(Use u | exists(Use u |
u = second mkElement(u) = second
and and
first.(Use).reaches(false, var, u) unresolveElement(first).(Use).reaches(false, var, u)
and and
u.getVariable(false) = var u.getVariable(false) = var
) )
@@ -76,7 +76,7 @@ predicate useUsePair(SemanticStackVariable var, Expr first, Expr second) {
predicate parameterUsePair(Parameter p, VariableAccess va) { predicate parameterUsePair(Parameter p, VariableAccess va) {
not parameterIsOverwritten(_, p) and va.getTarget() = p not parameterIsOverwritten(_, p) and va.getTarget() = p
or or
exists(ParameterDef pd | pd.reaches(true, p, (Use)va)) exists(ParameterDef pd | pd.reaches(true, p, (Use)unresolveElement(va)))
} }
/** /**
@@ -88,7 +88,7 @@ class DefOrUse extends @cfgnode {
// Uninstantiated templates are purely syntax, and only on instantiation // Uninstantiated templates are purely syntax, and only on instantiation
// will they be complete with information about types, conversions, call // will they be complete with information about types, conversions, call
// targets, etc. // targets, etc.
not this.(Element).isFromUninstantiatedTemplate(_) not mkElement(this).isFromUninstantiatedTemplate(_)
} }
/** /**
@@ -104,7 +104,7 @@ class DefOrUse extends @cfgnode {
pragma[noinline] pragma[noinline]
private predicate reaches_helper(boolean isDef, SemanticStackVariable v, BasicBlock bb, int i) { private predicate reaches_helper(boolean isDef, SemanticStackVariable v, BasicBlock bb, int i) {
getVariable(isDef) = v and getVariable(isDef) = v and
bb.getNode(i) = this bb.getNode(i) = mkElement(this)
} }
/** /**
@@ -140,7 +140,7 @@ class DefOrUse extends @cfgnode {
exists(BasicBlock bb, int i | exists(BasicBlock bb, int i |
getVariable(isDef) = v getVariable(isDef) = v
and and
bb.getNode(i) = this bb.getNode(i) = mkElement(this)
and and
j = min(int k | bbBarrierAt(bb, k, v, _) and k > i) j = min(int k | bbBarrierAt(bb, k, v, _) and k > i)
) )
@@ -153,11 +153,11 @@ class DefOrUse extends @cfgnode {
library library
class Def extends DefOrUse { class Def extends DefOrUse {
Def() { Def() {
definition(_, this) definition(_, mkElement(this))
} }
override SemanticStackVariable getVariable(boolean isDef) { override SemanticStackVariable getVariable(boolean isDef) {
definition(result, this) and isDef = true definition(result, mkElement(this)) and isDef = true
} }
} }
@@ -172,11 +172,11 @@ class ParameterDef extends DefOrUse {
ParameterDef() { ParameterDef() {
// Optimization: parameters that are not overwritten do not require // Optimization: parameters that are not overwritten do not require
// reachability analysis // reachability analysis
exists(Function f | parameterIsOverwritten(f, _) | this = f.getEntryPoint()) exists(Function f | parameterIsOverwritten(f, _) | mkElement(this) = f.getEntryPoint())
} }
override SemanticStackVariable getVariable(boolean isDef) { override SemanticStackVariable getVariable(boolean isDef) {
exists(Function f | parameterIsOverwritten(f, result) | this = f.getEntryPoint()) exists(Function f | parameterIsOverwritten(f, result) | mkElement(this) = f.getEntryPoint())
and and
isDef = true isDef = true
} }
@@ -185,22 +185,22 @@ class ParameterDef extends DefOrUse {
library library
class Use extends DefOrUse { class Use extends DefOrUse {
Use() { Use() {
useOfVar(_, this) useOfVar(_, mkElement(this))
} }
override SemanticStackVariable getVariable(boolean isDef) { override SemanticStackVariable getVariable(boolean isDef) {
useOfVar(result, this) and isDef = false useOfVar(result, mkElement(this)) and isDef = false
} }
} }
private predicate bbUseAt(BasicBlock bb, int i, SemanticStackVariable v, Use use) { private predicate bbUseAt(BasicBlock bb, int i, SemanticStackVariable v, Use use) {
bb.getNode(i) = use bb.getNode(i) = mkElement(use)
and and
use.getVariable(false) = v use.getVariable(false) = v
} }
private predicate bbDefAt(BasicBlock bb, int i, SemanticStackVariable v, Def def) { private predicate bbDefAt(BasicBlock bb, int i, SemanticStackVariable v, Def def) {
bb.getNode(i) = def bb.getNode(i) = mkElement(def)
and and
def.getVariable(true) = v def.getVariable(true) = v
} }
@@ -403,8 +403,8 @@ predicate useOfVarActual(SemanticStackVariable v, VariableAccess use) {
private predicate excludeReachesFunction(Function f) { private predicate excludeReachesFunction(Function f) {
exists(int defOrUses | exists(int defOrUses |
defOrUses = defOrUses =
count(Def def | def.(ControlFlowNode).getControlFlowScope() = f) + count(Def def | mkElement(def).(ControlFlowNode).getControlFlowScope() = f) +
count(Use use | use.(ControlFlowNode).getControlFlowScope() = f) and count(Use use | mkElement(use).(ControlFlowNode).getControlFlowScope() = f) and
defOrUses >= 13000 defOrUses >= 13000
) )
} }

View File

@@ -28,6 +28,11 @@ predicate functionEntry(ControlFlowNode entry) {
and not hasMultiScopeNode(function)) and not hasMultiScopeNode(function))
} }
/** Holds if `entry` is the entry point of a function. */
predicate functionEntryBB(@cfgnode entry) {
functionEntry(mkElement(entry))
}
/** /**
* Holds if `dest` is an immediate successor of `src` in the control-flow graph. * Holds if `dest` is an immediate successor of `src` in the control-flow graph.
*/ */
@@ -65,7 +70,7 @@ predicate dominates(ControlFlowNode dominator, ControlFlowNode node) {
* Holds if `dominator` is an immediate dominator of `node` in the control-flow * Holds if `dominator` is an immediate dominator of `node` in the control-flow
* graph of basic blocks. * graph of basic blocks.
*/ */
predicate bbIDominates(BasicBlock dom, BasicBlock node) = idominance(functionEntry/1, bb_successor/2)(_, dom, node) predicate bbIDominates(BasicBlock dom, BasicBlock node) = idominance(functionEntryBB/1, bb_successor/2)(_, dom, node)
/** /**
* Holds if `dominator` is a strict dominator of `node` in the control-flow * Holds if `dominator` is a strict dominator of `node` in the control-flow

View File

@@ -93,12 +93,12 @@ class GuardCondition extends Expr {
exists(BasicBlock thisblock exists(BasicBlock thisblock
| thisblock.contains(this) | thisblock.contains(this)
| exists(BasicBlock succ | exists(BasicBlock succ
| testIsTrue = true and succ = this.getATrueSuccessor() or | testIsTrue = true and mkElement(succ) = this.getATrueSuccessor() or
testIsTrue = false and succ = this.getAFalseSuccessor() testIsTrue = false and mkElement(succ) = this.getAFalseSuccessor()
| bbDominates(succ, controlled) and | bbDominates(succ, controlled) and
forall(BasicBlock pred forall(BasicBlock pred
| pred.getASuccessor() = succ | pred.getASuccessor() = succ
| pred = thisblock or bbDominates(succ, pred) or not reachable(pred)))) | pred = thisblock or bbDominates(succ, pred) or not reachable(mkElement(pred)))))
} }
} }

View File

@@ -21,7 +21,7 @@ library class StandardSSA extends SSAHelper {
class SsaDefinition extends @cfgnode { class SsaDefinition extends @cfgnode {
SsaDefinition() { SsaDefinition() {
exists(StandardSSA x | x.ssa_defn(_, (ControlFlowNode)this, _, _)) exists(StandardSSA x | x.ssa_defn(_, (ControlFlowNode)mkElement(this), _, _))
} }
/** /**
@@ -29,7 +29,7 @@ class SsaDefinition extends @cfgnode {
* this definition. * this definition.
*/ */
LocalScopeVariable getAVariable() { LocalScopeVariable getAVariable() {
exists(StandardSSA x | x.ssa_defn(result, (ControlFlowNode)this, _, _)) exists(StandardSSA x | x.ssa_defn(result, (ControlFlowNode)mkElement(this), _, _))
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */
@@ -42,12 +42,12 @@ class SsaDefinition extends @cfgnode {
* (this, v). * (this, v).
*/ */
string toString(LocalScopeVariable v) { string toString(LocalScopeVariable v) {
exists(StandardSSA x | result = x.toString((ControlFlowNode)this, v)) exists(StandardSSA x | result = x.toString((ControlFlowNode)mkElement(this), v))
} }
/** Gets a use of the SSA variable represented by the pair (this, v). */ /** Gets a use of the SSA variable represented by the pair (this, v). */
VariableAccess getAUse(LocalScopeVariable v) { VariableAccess getAUse(LocalScopeVariable v) {
exists(StandardSSA x | result = x.getAUse((ControlFlowNode)this, v)) exists(StandardSSA x | result = x.getAUse((ControlFlowNode)mkElement(this), v))
} }
/** /**
@@ -63,7 +63,7 @@ class SsaDefinition extends @cfgnode {
* the node where control flow is joined from multiple paths. * the node where control flow is joined from multiple paths.
*/ */
ControlFlowNode getDefinition() { ControlFlowNode getDefinition() {
result = this result = mkElement(this)
} }
BasicBlock getBasicBlock() { BasicBlock getBasicBlock() {
@@ -76,12 +76,12 @@ class SsaDefinition extends @cfgnode {
} }
Location getLocation() { Location getLocation() {
result = this.(ControlFlowNode).getLocation() result = mkElement(this).(ControlFlowNode).getLocation()
} }
/** Holds if the SSA variable `(this, p)` is defined by parameter `p`. */ /** Holds if the SSA variable `(this, p)` is defined by parameter `p`. */
predicate definedByParameter(Parameter p) { predicate definedByParameter(Parameter p) {
this = p.getFunction().getEntryPoint() mkElement(this) = p.getFunction().getEntryPoint()
} }
/** /**
@@ -133,7 +133,7 @@ class SsaDefinition extends @cfgnode {
/** Holds if `(this, v)` reaches the end of basic block `b`. */ /** Holds if `(this, v)` reaches the end of basic block `b`. */
predicate reachesEndOfBB(LocalScopeVariable v, BasicBlock b) { predicate reachesEndOfBB(LocalScopeVariable v, BasicBlock b) {
exists(StandardSSA x | x.ssaDefinitionReachesEndOfBB(v, (ControlFlowNode)this, b)) exists(StandardSSA x | x.ssaDefinitionReachesEndOfBB(v, (ControlFlowNode)mkElement(this), b))
} }
/** /**

View File

@@ -29,7 +29,7 @@ predicate var_definition(LocalScopeVariable v, ControlFlowNode node) {
else definition(v, node)) else definition(v, node))
or or
v instanceof Parameter and exists(BasicBlock b | b.getStart() = node and not exists(b.getAPredecessor()) and v instanceof Parameter and exists(BasicBlock b | b.getStart() = node and not exists(b.getAPredecessor()) and
b = v.(Parameter).getFunction().getEntryPoint()) mkElement(b) = v.(Parameter).getFunction().getEntryPoint())
} }
/** /**
@@ -251,7 +251,7 @@ cached library class SSAHelper extends int {
* `(node, v)`. * `(node, v)`.
*/ */
cached string toString(ControlFlowNode node, LocalScopeVariable v) { cached string toString(ControlFlowNode node, LocalScopeVariable v) {
if phi_node(v, (BasicBlock)node) then if phi_node(v, (BasicBlock)unresolveElement(node)) then
result = "SSA phi(" + v.getName() + ")" result = "SSA phi(" + v.getName() + ")"
else else
(ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")") (ssa_defn(v, node, _, _) and result = "SSA def(" + v.getName() + ")")

View File

@@ -22,7 +22,7 @@ abstract class SubBasicBlockCutNode extends @cfgnode {
// Some control-flow nodes are not in any basic block. This includes // Some control-flow nodes are not in any basic block. This includes
// `Conversion`s, expressions that are evaluated at compile time, default // `Conversion`s, expressions that are evaluated at compile time, default
// arguments, and `Function`s without implementation. // arguments, and `Function`s without implementation.
exists(this.(ControlFlowNode).getBasicBlock()) exists(mkElement(this).(ControlFlowNode).getBasicBlock())
} }
string toString() { result = "SubBasicBlockCutNode" } string toString() { result = "SubBasicBlockCutNode" }
} }
@@ -45,7 +45,7 @@ class SubBasicBlock extends @cfgnode {
/** Gets the basic block in which this `SubBasicBlock` is contained. */ /** Gets the basic block in which this `SubBasicBlock` is contained. */
BasicBlock getBasicBlock() { BasicBlock getBasicBlock() {
result = this.(ControlFlowNode).getBasicBlock() result = mkElement(this).(ControlFlowNode).getBasicBlock()
} }
/** /**
@@ -73,9 +73,9 @@ class SubBasicBlock extends @cfgnode {
*/ */
int getPosInBasicBlock(BasicBlock bb) { int getPosInBasicBlock(BasicBlock bb) {
exists(int nodePos, int rnk | exists(int nodePos, int rnk |
bb = this.(ControlFlowNode).getBasicBlock() and bb = mkElement(this).(ControlFlowNode).getBasicBlock() and
this = bb.getNode(nodePos) and mkElement(this) = bb.getNode(nodePos) and
nodePos = rank[rnk](int i | exists(SubBasicBlock n | n = bb.getNode(i))) and nodePos = rank[rnk](int i | exists(SubBasicBlock n | mkElement(n) = bb.getNode(i))) and
result = rnk - 1 result = rnk - 1
) )
} }
@@ -97,7 +97,7 @@ class SubBasicBlock extends @cfgnode {
*/ */
ControlFlowNode getNode(int pos) { ControlFlowNode getNode(int pos) {
exists(BasicBlock bb | bb = this.getBasicBlock() | exists(BasicBlock bb | bb = this.getBasicBlock() |
exists(int thisPos | this = bb.getNode(thisPos) | exists(int thisPos | mkElement(this) = bb.getNode(thisPos) |
result = bb.getNode(thisPos + pos) and result = bb.getNode(thisPos + pos) and
pos >= 0 and pos >= 0 and
pos < this.getNumberOfNodes() pos < this.getNumberOfNodes()
@@ -148,13 +148,13 @@ class SubBasicBlock extends @cfgnode {
*/ */
int getNumberOfNodes() { int getNumberOfNodes() {
exists(BasicBlock bb | bb = this.getBasicBlock() | exists(BasicBlock bb | bb = this.getBasicBlock() |
exists(int thisPos | this = bb.getNode(thisPos) | exists(int thisPos | mkElement(this) = bb.getNode(thisPos) |
this.lastInBB() and this.lastInBB() and
result = bb.length() - thisPos result = bb.length() - thisPos
or or
exists(SubBasicBlock succ, int succPos | exists(SubBasicBlock succ, int succPos |
succ.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1 and succ.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1 and
bb.getNode(succPos) = succ and bb.getNode(succPos) = mkElement(succ) and
result = succPos - thisPos result = succPos - thisPos
) )
) )
@@ -168,7 +168,7 @@ class SubBasicBlock extends @cfgnode {
/** Gets the first control-flow node in this `SubBasicBlock`. */ /** Gets the first control-flow node in this `SubBasicBlock`. */
ControlFlowNode getStart() { ControlFlowNode getStart() {
result = this result = mkElement(this)
} }
pragma[noinline] pragma[noinline]

View File

@@ -63,8 +63,8 @@ private predicate nonAnalyzableFunction(Function f) {
*/ */
private predicate impossibleFalseEdge(Expr condition, @cfgnode succ) { private predicate impossibleFalseEdge(Expr condition, @cfgnode succ) {
conditionAlwaysTrue(condition) conditionAlwaysTrue(condition)
and falsecond(condition,succ) and falsecond(unresolveElement(condition),succ)
and not truecond(condition,succ) and not truecond(unresolveElement(condition),succ)
} }
/** /**
@@ -72,8 +72,8 @@ private predicate impossibleFalseEdge(Expr condition, @cfgnode succ) {
*/ */
private predicate impossibleTrueEdge(Expr condition, @cfgnode succ) { private predicate impossibleTrueEdge(Expr condition, @cfgnode succ) {
conditionAlwaysFalse(condition) conditionAlwaysFalse(condition)
and truecond(condition,succ) and truecond(unresolveElement(condition),succ)
and not falsecond(condition,succ) and not falsecond(unresolveElement(condition),succ)
} }
/** /**
@@ -93,7 +93,7 @@ private int switchCaseRangeEnd(SwitchCase sc) {
*/ */
private @cfgnode getASwitchExpr(SwitchStmt switch, Block switchBlock) { private @cfgnode getASwitchExpr(SwitchStmt switch, Block switchBlock) {
switch.getStmt() = switchBlock and switch.getStmt() = switchBlock and
successors_extended(result, switchBlock) successors_extended(result, unresolveElement(switchBlock))
} }
/** /**
@@ -111,7 +111,7 @@ private predicate impossibleSwitchEdge(Block switchBlock, SwitchCase sc) {
and forall(@cfgnode n | and forall(@cfgnode n |
n = getASwitchExpr(switch, switchBlock) | n = getASwitchExpr(switch, switchBlock) |
exists(int switchValue | exists(int switchValue |
switchValue = getSwitchValue(n) switchValue = getSwitchValue(mkElement(n))
and (switchValue < sc.getExpr().(CompileTimeConstantInt).getIntValue() or and (switchValue < sc.getExpr().(CompileTimeConstantInt).getIntValue() or
switchValue > switchCaseRangeEnd(sc))))) switchValue > switchCaseRangeEnd(sc)))))
} }
@@ -130,7 +130,7 @@ private predicate impossibleDefaultSwitchEdge(Block switchBlock, DefaultCase dc)
n = getASwitchExpr(switch, switchBlock) | n = getASwitchExpr(switch, switchBlock) |
exists(SwitchCase sc, int val | exists(SwitchCase sc, int val |
sc.getSwitchStmt() = switch and sc.getSwitchStmt() = switch and
val = getSwitchValue(n) and val = getSwitchValue(mkElement(n)) and
val >= sc.getExpr().(CompileTimeConstantInt).getIntValue() and val >= sc.getExpr().(CompileTimeConstantInt).getIntValue() and
val <= switchCaseRangeEnd(sc)))) val <= switchCaseRangeEnd(sc))))
} }
@@ -140,9 +140,9 @@ private predicate impossibleDefaultSwitchEdge(Block switchBlock, DefaultCase dc)
* (at least) one such target must be potentially returning. * (at least) one such target must be potentially returning.
*/ */
private predicate possiblePredecessor(@cfgnode pred) { private predicate possiblePredecessor(@cfgnode pred) {
not exists(pred.(FunctionCall).getTarget()) not exists(mkElement(pred).(FunctionCall).getTarget())
or or
potentiallyReturningFunctionCall(pred) potentiallyReturningFunctionCall(mkElement(pred))
} }
/** /**
@@ -153,11 +153,11 @@ private predicate possiblePredecessor(@cfgnode pred) {
cached predicate successors_adapted(@cfgnode pred, @cfgnode succ) { cached predicate successors_adapted(@cfgnode pred, @cfgnode succ) {
successors_extended(pred, succ) successors_extended(pred, succ)
and possiblePredecessor(pred) and possiblePredecessor(pred)
and not impossibleFalseEdge(pred, succ) and not impossibleFalseEdge(mkElement(pred), succ)
and not impossibleTrueEdge(pred, succ) and not impossibleTrueEdge(mkElement(pred), succ)
and not impossibleSwitchEdge(pred, succ) and not impossibleSwitchEdge(mkElement(pred), mkElement(succ))
and not impossibleDefaultSwitchEdge(pred, succ) and not impossibleDefaultSwitchEdge(mkElement(pred), mkElement(succ))
and not getOptions().exprExits(pred) and not getOptions().exprExits(mkElement(pred))
} }
private predicate compileTimeConstantInt(Expr e, int val) { private predicate compileTimeConstantInt(Expr e, int val) {
@@ -708,9 +708,9 @@ library class ConditionEvaluator extends ExprEvaluator {
ConditionEvaluator() { this = 0 } ConditionEvaluator() { this = 0 }
override predicate interesting(Expr e) { override predicate interesting(Expr e) {
falsecond(e, _) falsecond(unresolveElement(e), _)
or or
truecond(e, _) truecond(unresolveElement(e), _)
} }
} }
@@ -719,7 +719,7 @@ library class SwitchEvaluator extends ExprEvaluator {
SwitchEvaluator() { this = 1 } SwitchEvaluator() { this = 1 }
override predicate interesting(Expr e) { override predicate interesting(Expr e) {
e = getASwitchExpr(_, _) e = mkElement(getASwitchExpr(_, _))
} }
} }

View File

@@ -31,7 +31,7 @@ private cached module Cached {
// then the node is the start of a new primitive basic block. // then the node is the start of a new primitive basic block.
or or
strictcount (ControlFlowNode pred, ControlFlowNode other strictcount (ControlFlowNode pred, ControlFlowNode other
| successors_extended(pred,node) and successors_extended(pred,other)) > 1 | successors_extended(unresolveElement(pred),unresolveElement(node)) and successors_extended(unresolveElement(pred),unresolveElement(other))) > 1
// If the node has zero predecessors then it is the start of // If the node has zero predecessors then it is the start of
// a BB. However, the C++ AST contains many nodes with zero // a BB. However, the C++ AST contains many nodes with zero
@@ -39,17 +39,17 @@ private cached module Cached {
// the CFG. So we exclude all of those trivial BBs by requiring // the CFG. So we exclude all of those trivial BBs by requiring
// that the node have at least one successor. // that the node have at least one successor.
or or
(not successors_extended(_, node) and successors_extended(node, _)) (not successors_extended(_, unresolveElement(node)) and successors_extended(unresolveElement(node), _))
} }
/** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */ /** Holds if `node` is the `pos`th control-flow node in primitive basic block `bb`. */
cached cached
predicate primitive_basic_block_member(ControlFlowNode node, PrimitiveBasicBlock bb, int pos) { predicate primitive_basic_block_member(ControlFlowNode node, PrimitiveBasicBlock bb, int pos) {
(node = bb and pos = 0) (node = mkElement(bb) and pos = 0)
or or
(not (node instanceof PrimitiveBasicBlock) and (not (unresolveElement(node) instanceof PrimitiveBasicBlock) and
exists (ControlFlowNode pred exists (ControlFlowNode pred
| successors_extended(pred,node) | successors_extended(unresolveElement(pred),unresolveElement(node))
| primitive_basic_block_member(pred, bb, pos - 1))) | primitive_basic_block_member(pred, bb, pos - 1)))
} }
@@ -64,7 +64,7 @@ private cached module Cached {
predicate primitive_bb_successor(PrimitiveBasicBlock pred, PrimitiveBasicBlock succ) { predicate primitive_bb_successor(PrimitiveBasicBlock pred, PrimitiveBasicBlock succ) {
exists(ControlFlowNode last | exists(ControlFlowNode last |
primitive_basic_block_member(last, pred, primitive_bb_length(pred)-1) and primitive_basic_block_member(last, pred, primitive_bb_length(pred)-1) and
successors_extended(last, succ) successors_extended(unresolveElement(last), succ)
) )
} }
} }
@@ -76,7 +76,7 @@ private cached module Cached {
class PrimitiveBasicBlock extends @cfgnode { class PrimitiveBasicBlock extends @cfgnode {
PrimitiveBasicBlock() { PrimitiveBasicBlock() {
primitive_basic_block_entry_node(this) primitive_basic_block_entry_node(mkElement(this))
} }
/** Gets a textual representation of this element. */ /** Gets a textual representation of this element. */

View File

@@ -169,7 +169,7 @@ predicate stackPointerFlowsToDef(
or or
// Increment/decrement operators. // Increment/decrement operators.
exists (VariableAccess access exists (VariableAccess access
| access = def.(CrementOperation).getOperand() and | access = mkElement(def).(CrementOperation).getOperand() and
var = access.getTarget() and var = access.getTarget() and
stackPointerFlowsToUse(access, useType, source, isLocal)) stackPointerFlowsToUse(access, useType, source, isLocal))
or or
@@ -205,7 +205,7 @@ predicate stackReferenceFlowsToDef_Impl(
or or
// Increment/decrement operators. // Increment/decrement operators.
exists (VariableAccess access exists (VariableAccess access
| access = def.(CrementOperation).getOperand() and | access = mkElement(def).(CrementOperation).getOperand() and
var = access.getTarget() and var = access.getTarget() and
stackReferenceFlowsToUse(access, useType, source, isLocal)) stackReferenceFlowsToUse(access, useType, source, isLocal))
or or

View File

@@ -114,7 +114,7 @@ module FlowVar_internal {
predicate blockVarDefinedByVariable( predicate blockVarDefinedByVariable(
SubBasicBlock sbb, LocalScopeVariable v) SubBasicBlock sbb, LocalScopeVariable v)
{ {
sbb = v.(Parameter).getFunction().getEntryPoint() mkElement(sbb) = v.(Parameter).getFunction().getEntryPoint()
or or
exists(DeclStmt declStmt | exists(DeclStmt declStmt |
declStmt.getDeclaration(_) = v.(LocalVariable) and declStmt.getDeclaration(_) = v.(LocalVariable) and
@@ -131,11 +131,11 @@ module FlowVar_internal {
or or
TBlockVar(SubBasicBlock sbb, Variable v) { TBlockVar(SubBasicBlock sbb, Variable v) {
not fullySupportedSsaVariable(v) and not fullySupportedSsaVariable(v) and
reachable(sbb) and reachable(mkElement(sbb)) and
( (
initializer(sbb.getANode(), v, _) initializer(sbb.getANode(), v, _)
or or
assignmentLikeOperation(sbb, v, _) assignmentLikeOperation(mkElement(sbb), v, _)
or or
blockVarDefinedByVariable(sbb, v) blockVarDefinedByVariable(sbb, v)
) )
@@ -233,7 +233,7 @@ module FlowVar_internal {
override predicate definedByExpr(Expr e, ControlFlowNode node) { override predicate definedByExpr(Expr e, ControlFlowNode node) {
assignmentLikeOperation(node, v, e) and assignmentLikeOperation(node, v, e) and
node = sbb node = mkElement(sbb)
or or
initializer(node, v, e) and initializer(node, v, e) and
node = sbb.getANode() node = sbb.getANode()
@@ -310,7 +310,7 @@ module FlowVar_internal {
} }
private predicate bbInLoop(BasicBlock bb) { private predicate bbInLoop(BasicBlock bb) {
bbDominates(this.(Loop).getStmt(), bb) bbDominates(unresolveElement(this.(Loop).getStmt()), bb)
or or
bbInLoopCondition(bb) bbInLoopCondition(bb)
} }
@@ -328,7 +328,7 @@ module FlowVar_internal {
( (
// For the type of loop we are interested in, the body is always a // For the type of loop we are interested in, the body is always a
// basic block. // basic block.
bb = this.(Loop).getStmt() and mkElement(bb) = this.(Loop).getStmt() and
v = this.getARelevantVariable() v = this.getARelevantVariable()
or or
reachesWithoutAssignment(bb.getAPredecessor(), v) and reachesWithoutAssignment(bb.getAPredecessor(), v) and
@@ -369,7 +369,7 @@ module FlowVar_internal {
mid = getAReachedBlockVarSBB(start) and mid = getAReachedBlockVarSBB(start) and
result = mid.getASuccessor() and result = mid.getASuccessor() and
not skipLoop(mid, result, sbbDef, v) and not skipLoop(mid, result, sbbDef, v) and
not assignmentLikeOperation(result, v, _) not assignmentLikeOperation(mkElement(result), v, _)
) )
} }
@@ -522,7 +522,7 @@ module FlowVar_internal {
DataFlowSubBasicBlockCutNode() { DataFlowSubBasicBlockCutNode() {
exists(Variable v | exists(Variable v |
not fullySupportedSsaVariable(v) and not fullySupportedSsaVariable(v) and
assignmentLikeOperation(this, v, _) assignmentLikeOperation(mkElement(this), v, _)
// It is not necessary to cut the basic blocks at `Initializer` nodes // It is not necessary to cut the basic blocks at `Initializer` nodes
// because the affected variable can have no _other_ value before its // because the affected variable can have no _other_ value before its
// initializer. It is not necessary to cut basic blocks at procedure // initializer. It is not necessary to cut basic blocks at procedure

View File

@@ -26,7 +26,7 @@ abstract class SubBasicBlockCutNode extends @cfgnode {
// Some control-flow nodes are not in any basic block. This includes // Some control-flow nodes are not in any basic block. This includes
// `Conversion`s, expressions that are evaluated at compile time, default // `Conversion`s, expressions that are evaluated at compile time, default
// arguments, and `Function`s without implementation. // arguments, and `Function`s without implementation.
exists(this.(ControlFlowNode).getBasicBlock()) exists(mkElement(this).(ControlFlowNode).getBasicBlock())
} }
string toString() { result = "SubBasicBlockCutNode" } string toString() { result = "SubBasicBlockCutNode" }
} }
@@ -49,7 +49,7 @@ class SubBasicBlock extends @cfgnode {
/** Gets the basic block in which this `SubBasicBlock` is contained. */ /** Gets the basic block in which this `SubBasicBlock` is contained. */
BasicBlock getBasicBlock() { BasicBlock getBasicBlock() {
result = this.(ControlFlowNode).getBasicBlock() result = mkElement(this).(ControlFlowNode).getBasicBlock()
} }
/** /**
@@ -77,9 +77,9 @@ class SubBasicBlock extends @cfgnode {
*/ */
int getPosInBasicBlock(BasicBlock bb) { int getPosInBasicBlock(BasicBlock bb) {
exists(int nodePos, int rnk | exists(int nodePos, int rnk |
bb = this.(ControlFlowNode).getBasicBlock() and bb = mkElement(this).(ControlFlowNode).getBasicBlock() and
this = bb.getNode(nodePos) and mkElement(this) = bb.getNode(nodePos) and
nodePos = rank[rnk](int i | exists(SubBasicBlock n | n = bb.getNode(i))) and nodePos = rank[rnk](int i | exists(SubBasicBlock n | mkElement(n) = bb.getNode(i))) and
result = rnk - 1 result = rnk - 1
) )
} }
@@ -101,7 +101,7 @@ class SubBasicBlock extends @cfgnode {
*/ */
ControlFlowNode getNode(int pos) { ControlFlowNode getNode(int pos) {
exists(BasicBlock bb | bb = this.getBasicBlock() | exists(BasicBlock bb | bb = this.getBasicBlock() |
exists(int thisPos | this = bb.getNode(thisPos) | exists(int thisPos | mkElement(this) = bb.getNode(thisPos) |
result = bb.getNode(thisPos + pos) and result = bb.getNode(thisPos + pos) and
pos >= 0 and pos >= 0 and
pos < this.getNumberOfNodes() pos < this.getNumberOfNodes()
@@ -152,13 +152,13 @@ class SubBasicBlock extends @cfgnode {
*/ */
int getNumberOfNodes() { int getNumberOfNodes() {
exists(BasicBlock bb | bb = this.getBasicBlock() | exists(BasicBlock bb | bb = this.getBasicBlock() |
exists(int thisPos | this = bb.getNode(thisPos) | exists(int thisPos | mkElement(this) = bb.getNode(thisPos) |
this.lastInBB() and this.lastInBB() and
result = bb.length() - thisPos result = bb.length() - thisPos
or or
exists(SubBasicBlock succ, int succPos | exists(SubBasicBlock succ, int succPos |
succ.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1 and succ.getPosInBasicBlock(bb) = this.getPosInBasicBlock(bb) + 1 and
bb.getNode(succPos) = succ and bb.getNode(succPos) = mkElement(succ) and
result = succPos - thisPos result = succPos - thisPos
) )
) )
@@ -172,7 +172,7 @@ class SubBasicBlock extends @cfgnode {
/** Gets the first control-flow node in this `SubBasicBlock`. */ /** Gets the first control-flow node in this `SubBasicBlock`. */
ControlFlowNode getStart() { ControlFlowNode getStart() {
result = this result = mkElement(this)
} }
pragma[noinline] pragma[noinline]

View File

@@ -25,11 +25,11 @@ abstract class Access extends Expr, NameQualifiableElement {
*/ */
class EnumConstantAccess extends Access, @varaccess { class EnumConstantAccess extends Access, @varaccess {
EnumConstantAccess() { EnumConstantAccess() {
exists(EnumConstant c | varbind(this, c)) exists(EnumConstant c | varbind(unresolveElement(this), unresolveElement(c)))
} }
/** Gets the accessed enum constant. */ /** Gets the accessed enum constant. */
override EnumConstant getTarget() { varbind(this, result) } override EnumConstant getTarget() { varbind(unresolveElement(this), unresolveElement(result)) }
/** Gets a textual representation of this enum constant access. */ /** Gets a textual representation of this enum constant access. */
override string toString() { result = this.getTarget().getName() } override string toString() { result = this.getTarget().getName() }
@@ -40,11 +40,11 @@ class EnumConstantAccess extends Access, @varaccess {
*/ */
class VariableAccess extends Access, @varaccess { class VariableAccess extends Access, @varaccess {
VariableAccess() { VariableAccess() {
not exists(EnumConstant c | varbind(this, c)) not exists(EnumConstant c | varbind(unresolveElement(this), unresolveElement(c)))
} }
/** Gets the accessed variable. */ /** Gets the accessed variable. */
override Variable getTarget() { varbind(this, result) } override Variable getTarget() { varbind(unresolveElement(this), unresolveElement(result)) }
/** /**
* Holds if this variable access is providing an LValue in a meaningful way. * Holds if this variable access is providing an LValue in a meaningful way.
@@ -133,7 +133,7 @@ class VariableAccess extends Access, @varaccess {
* A C/C++ field access expression. * A C/C++ field access expression.
*/ */
class FieldAccess extends VariableAccess { class FieldAccess extends VariableAccess {
FieldAccess() { exists(Field f | varbind(this, f)) } FieldAccess() { exists(Field f | varbind(unresolveElement(this), unresolveElement(f))) }
/** Gets the accessed field. */ /** Gets the accessed field. */
override Field getTarget() { result = super.getTarget() } override Field getTarget() { result = super.getTarget() }
@@ -229,10 +229,12 @@ class ImplicitThisFieldAccess extends FieldAccess {
* A C/C++ function access expression. * A C/C++ function access expression.
*/ */
class FunctionAccess extends Access, @routineexpr { class FunctionAccess extends Access, @routineexpr {
FunctionAccess() { not iscall(this,_) } FunctionAccess() {
not iscall(unresolveElement(this),_)
}
/** Gets the accessed function. */ /** Gets the accessed function. */
override Function getTarget() { funbind(this, result) } override Function getTarget() { funbind(unresolveElement(this), unresolveElement(result)) }
/** Gets a textual representation of this function access. */ /** Gets a textual representation of this function access. */
override string toString() { override string toString() {

View File

@@ -102,7 +102,7 @@ class AssignAndExpr extends AssignBitwiseOperation, @assignandexpr {
/** /**
* A non-overloaded `|=` assignment expression. * A non-overloaded `|=` assignment expression.
*/ */
class AssignOrExpr extends AssignBitwiseOperation, @assignorexpr { class AssignOrExpr extends AssignBitwiseOperation, @assignorexpr {
override string getOperator() { result = "|=" } override string getOperator() { result = "|=" }
} }
@@ -116,14 +116,14 @@ class AssignXorExpr extends AssignBitwiseOperation, @assignxorexpr {
/** /**
* A non-overloaded `<<=` assignment expression. * A non-overloaded `<<=` assignment expression.
*/ */
class AssignLShiftExpr extends AssignBitwiseOperation, @assignlshiftexpr { class AssignLShiftExpr extends AssignBitwiseOperation, @assignlshiftexpr {
override string getOperator() { result = "<<=" } override string getOperator() { result = "<<=" }
} }
/** /**
* A non-overloaded `>>=` assignment expression. * A non-overloaded `>>=` assignment expression.
*/ */
class AssignRShiftExpr extends AssignBitwiseOperation, @assignrshiftexpr { class AssignRShiftExpr extends AssignBitwiseOperation, @assignrshiftexpr {
override string getOperator() { result = ">>=" } override string getOperator() { result = ">>=" }
} }
@@ -152,7 +152,7 @@ class ConditionDeclExpr extends Expr, @condition_decl {
Expr getExpr() { result = this.getChild(0) } Expr getExpr() { result = this.getChild(0) }
/** Gets the variable that is declared. */ /** Gets the variable that is declared. */
Variable getVariable() { condition_decl_bind(this,result) } Variable getVariable() { condition_decl_bind(unresolveElement(this),unresolveElement(result)) }
override string toString() { result = "(condition decl)" } override string toString() { result = "(condition decl)" }
} }

View File

@@ -145,7 +145,9 @@ abstract class Call extends Expr, NameQualifiableElement {
* 5. Base class initializers in constructors. * 5. Base class initializers in constructors.
*/ */
class FunctionCall extends Call, @funbindexpr { class FunctionCall extends Call, @funbindexpr {
FunctionCall() { iscall(this,_) } FunctionCall() {
iscall(unresolveElement(this),_)
}
/** Gets an explicit template argument for this call. */ /** Gets an explicit template argument for this call. */
Type getAnExplicitTemplateArgument() { Type getAnExplicitTemplateArgument() {
@@ -165,8 +167,8 @@ class FunctionCall extends Call, @funbindexpr {
/** Gets the number of explicit template arguments for this call. */ /** Gets the number of explicit template arguments for this call. */
int getNumberOfExplicitTemplateArguments() { int getNumberOfExplicitTemplateArguments() {
if numtemplatearguments(this,_) then if numtemplatearguments(unresolveElement(this),_) then
numtemplatearguments(this,result) numtemplatearguments(unresolveElement(this),result)
else else
result = 0 result = 0
} }
@@ -191,7 +193,7 @@ class FunctionCall extends Call, @funbindexpr {
/** Holds if a template argument list was provided for this call. */ /** Holds if a template argument list was provided for this call. */
predicate hasTemplateArgumentList() { predicate hasTemplateArgumentList() {
numtemplatearguments(this,_) numtemplatearguments(unresolveElement(this),_)
} }
/** /**
@@ -238,7 +240,7 @@ class FunctionCall extends Call, @funbindexpr {
* In the case of virtual function calls, the result is the most-specific function in the override tree (as * In the case of virtual function calls, the result is the most-specific function in the override tree (as
* determined by the compiler) such that the target at runtime will be one of result.getAnOverridingFunction*(). * determined by the compiler) such that the target at runtime will be one of result.getAnOverridingFunction*().
*/ */
override Function getTarget() { funbind(this,result) } override Function getTarget() { funbind(unresolveElement(this),unresolveElement(result)) }
/** /**
* 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.
@@ -251,7 +253,7 @@ class FunctionCall extends Call, @funbindexpr {
* Note that this holds even in cases where a sufficiently clever compiler could perform static dispatch. * Note that this holds even in cases where a sufficiently clever compiler could perform static dispatch.
*/ */
predicate isVirtual() { predicate isVirtual() {
iscall(this,1) iscall(unresolveElement(this),1)
} }
/** /**
@@ -259,7 +261,7 @@ class FunctionCall extends Call, @funbindexpr {
* found by any other means. * found by any other means.
*/ */
predicate isOnlyFoundByADL() { predicate isOnlyFoundByADL() {
iscall(this,2) iscall(unresolveElement(this),2)
} }
/** Gets a textual representation of this function call. */ /** Gets a textual representation of this function call. */
@@ -475,7 +477,7 @@ class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit
*/ */
class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit { class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
/** Gets the field being initialized. */ /** Gets the field being initialized. */
Field getTarget() { varbind(this,result) } Field getTarget() { varbind(unresolveElement(this),unresolveElement(result)) }
/** /**
* Gets the expression to which the field is initialized. * Gets the expression to which the field is initialized.
@@ -534,7 +536,7 @@ class DestructorVirtualDestruction extends DestructorBaseDestruction, @dtorvirtu
*/ */
class DestructorFieldDestruction extends DestructorDestruction, @dtorfielddestruct { class DestructorFieldDestruction extends DestructorDestruction, @dtorfielddestruct {
/** Gets the field being destructed. */ /** Gets the field being destructed. */
Field getTarget() { varbind(this,result) } Field getTarget() { varbind(unresolveElement(this),unresolveElement(result)) }
/** Gets the compiler-generated call to the variable's destructor. */ /** Gets the compiler-generated call to the variable's destructor. */
DestructorCall getExpr() { result = this.getChild(0) } DestructorCall getExpr() { result = this.getChild(0) }

View File

@@ -136,7 +136,7 @@ private predicate isPointerToMemberOrNullPointer(Type type) {
*/ */
class ArithmeticConversion extends Cast { class ArithmeticConversion extends Cast {
ArithmeticConversion() { ArithmeticConversion() {
conversionkinds(this, 0) and conversionkinds(unresolveElement(this), 0) and
isArithmeticOrEnum(getType().getUnspecifiedType()) and isArithmeticOrEnum(getType().getUnspecifiedType()) and
isArithmeticOrEnum(getExpr().getType().getUnspecifiedType()) isArithmeticOrEnum(getExpr().getType().getUnspecifiedType())
} }
@@ -210,7 +210,7 @@ class IntegralToFloatingPointConversion extends ArithmeticConversion {
*/ */
class PointerConversion extends Cast { class PointerConversion extends Cast {
PointerConversion() { PointerConversion() {
conversionkinds(this, 0) and conversionkinds(unresolveElement(this), 0) and
isPointerOrNullPointer(getType().getUnspecifiedType()) and isPointerOrNullPointer(getType().getUnspecifiedType()) and
isPointerOrNullPointer(getExpr().getType().getUnspecifiedType()) isPointerOrNullPointer(getExpr().getType().getUnspecifiedType())
} }
@@ -228,7 +228,7 @@ class PointerConversion extends Cast {
*/ */
class PointerToMemberConversion extends Cast { class PointerToMemberConversion extends Cast {
PointerToMemberConversion() { PointerToMemberConversion() {
conversionkinds(this, 0) and conversionkinds(unresolveElement(this), 0) and
exists(Type fromType, Type toType | exists(Type fromType, Type toType |
fromType = getExpr().getType().getUnspecifiedType() and fromType = getExpr().getType().getUnspecifiedType() and
toType = getType().getUnspecifiedType() and toType = getType().getUnspecifiedType() and
@@ -253,7 +253,7 @@ class PointerToMemberConversion extends Cast {
*/ */
class PointerToIntegralConversion extends Cast { class PointerToIntegralConversion extends Cast {
PointerToIntegralConversion() { PointerToIntegralConversion() {
conversionkinds(this, 0) and conversionkinds(unresolveElement(this), 0) and
isIntegralOrEnum(getType().getUnspecifiedType()) and isIntegralOrEnum(getType().getUnspecifiedType()) and
isPointerOrNullPointer(getExpr().getType().getUnspecifiedType()) isPointerOrNullPointer(getExpr().getType().getUnspecifiedType())
} }
@@ -268,7 +268,7 @@ class PointerToIntegralConversion extends Cast {
*/ */
class IntegralToPointerConversion extends Cast { class IntegralToPointerConversion extends Cast {
IntegralToPointerConversion() { IntegralToPointerConversion() {
conversionkinds(this, 0) and conversionkinds(unresolveElement(this), 0) and
isPointerOrNullPointer(getType().getUnspecifiedType()) and isPointerOrNullPointer(getType().getUnspecifiedType()) and
isIntegralOrEnum(getExpr().getType().getUnspecifiedType()) isIntegralOrEnum(getExpr().getType().getUnspecifiedType())
} }
@@ -284,7 +284,7 @@ class IntegralToPointerConversion extends Cast {
*/ */
class BoolConversion extends Cast { class BoolConversion extends Cast {
BoolConversion() { BoolConversion() {
conversionkinds(this, 1) conversionkinds(unresolveElement(this), 1)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -315,7 +315,7 @@ class VoidConversion extends Cast {
*/ */
class InheritanceConversion extends Cast { class InheritanceConversion extends Cast {
InheritanceConversion() { InheritanceConversion() {
conversionkinds(this, 2) or conversionkinds(this, 3) conversionkinds(unresolveElement(this), 2) or conversionkinds(unresolveElement(this), 3)
} }
/** /**
@@ -367,7 +367,7 @@ private Class getConversionClass(Expr expr) {
*/ */
class BaseClassConversion extends InheritanceConversion { class BaseClassConversion extends InheritanceConversion {
BaseClassConversion() { BaseClassConversion() {
conversionkinds(this, 2) conversionkinds(unresolveElement(this), 2)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -396,7 +396,7 @@ class BaseClassConversion extends InheritanceConversion {
*/ */
class DerivedClassConversion extends InheritanceConversion { class DerivedClassConversion extends InheritanceConversion {
DerivedClassConversion() { DerivedClassConversion() {
conversionkinds(this, 3) conversionkinds(unresolveElement(this), 3)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -418,7 +418,7 @@ class DerivedClassConversion extends InheritanceConversion {
*/ */
class PointerToMemberBaseClassConversion extends Cast { class PointerToMemberBaseClassConversion extends Cast {
PointerToMemberBaseClassConversion() { PointerToMemberBaseClassConversion() {
conversionkinds(this, 4) conversionkinds(unresolveElement(this), 4)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -432,7 +432,7 @@ class PointerToMemberBaseClassConversion extends Cast {
*/ */
class PointerToMemberDerivedClassConversion extends Cast { class PointerToMemberDerivedClassConversion extends Cast {
PointerToMemberDerivedClassConversion() { PointerToMemberDerivedClassConversion() {
conversionkinds(this, 5) conversionkinds(unresolveElement(this), 5)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -447,7 +447,7 @@ class PointerToMemberDerivedClassConversion extends Cast {
*/ */
class GlvalueConversion extends Cast { class GlvalueConversion extends Cast {
GlvalueConversion() { GlvalueConversion() {
conversionkinds(this, 6) conversionkinds(unresolveElement(this), 6)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -471,7 +471,7 @@ class GlvalueConversion extends Cast {
*/ */
class PrvalueAdjustmentConversion extends Cast { class PrvalueAdjustmentConversion extends Cast {
PrvalueAdjustmentConversion() { PrvalueAdjustmentConversion() {
conversionkinds(this, 7) conversionkinds(unresolveElement(this), 7)
} }
override string getSemanticConversionString() { override string getSemanticConversionString() {
@@ -503,7 +503,7 @@ class UuidofOperator extends Expr, @uuidof {
/** Gets the contained type. */ /** Gets the contained type. */
Type getTypeOperand() { Type getTypeOperand() {
uuidof_bind(this, result) uuidof_bind(unresolveElement(this), unresolveElement(result))
} }
} }
@@ -524,7 +524,7 @@ class TypeidOperator extends Expr, @type_id {
* printf("the type of ptr is: %s\n", typeid(ptr).name); * printf("the type of ptr is: %s\n", typeid(ptr).name);
* ``` * ```
*/ */
Type getResultType() { typeid_bind(this,unresolve(result)) } Type getResultType() { typeid_bind(unresolveElement(this),unresolveElement(result)) }
/** /**
* DEPRECATED: Use `getResultType()` instead. * DEPRECATED: Use `getResultType()` instead.
@@ -605,10 +605,10 @@ class SizeofExprOperator extends SizeofOperator {
* A C/C++ sizeof expression whose operand is a type name. * A C/C++ sizeof expression whose operand is a type name.
*/ */
class SizeofTypeOperator extends SizeofOperator { class SizeofTypeOperator extends SizeofOperator {
SizeofTypeOperator() { sizeof_bind(this,_) } SizeofTypeOperator() { sizeof_bind(unresolveElement(this),_) }
/** Gets the contained type. */ /** Gets the contained type. */
Type getTypeOperand() { sizeof_bind(this,unresolve(result)) } Type getTypeOperand() { sizeof_bind(unresolveElement(this),unresolveElement(result)) }
/** /**
* DEPRECATED: Use `getTypeOperand()` instead * DEPRECATED: Use `getTypeOperand()` instead
@@ -657,10 +657,10 @@ class AlignofExprOperator extends AlignofOperator {
* A C++11 `alignof` expression whose operand is a type name. * A C++11 `alignof` expression whose operand is a type name.
*/ */
class AlignofTypeOperator extends AlignofOperator { class AlignofTypeOperator extends AlignofOperator {
AlignofTypeOperator() { sizeof_bind(this,_) } AlignofTypeOperator() { sizeof_bind(unresolveElement(this),_) }
/** Gets the contained type. */ /** Gets the contained type. */
Type getTypeOperand() { sizeof_bind(this,unresolve(result)) } Type getTypeOperand() { sizeof_bind(unresolveElement(this),unresolveElement(result)) }
/** /**
* DEPRECATED: Use `getTypeOperand()` instead. * DEPRECATED: Use `getTypeOperand()` instead.

View File

@@ -8,7 +8,7 @@ private import semmle.code.cpp.internal.Type
*/ */
class Expr extends StmtParent, @expr { class Expr extends StmtParent, @expr {
/** Gets the nth child of this expression. */ /** Gets the nth child of this expression. */
Expr getChild(int n) { exprparents(result,n,this) } Expr getChild(int n) { exprparents(unresolveElement(result),n,unresolveElement(this)) }
/** Gets the number of direct children of this expression. */ /** Gets the number of direct children of this expression. */
int getNumChild() { result = count(this.getAChild()) } int getNumChild() { result = count(this.getAChild()) }
@@ -38,14 +38,14 @@ class Expr extends StmtParent, @expr {
Expr getAChild() { exists (int n | result = this.getChild(n)) } Expr getAChild() { exists (int n | result = this.getChild(n)) }
/** Gets the parent of this expression, if any. */ /** Gets the parent of this expression, if any. */
Element getParent() { exprparents(this,_,result) } Element getParent() { exprparents(unresolveElement(this),_,unresolveElement(result)) }
/** Gets the location of this expression. */ /** Gets the location of this expression. */
override Location getLocation() { exprs(this,_,result) } override Location getLocation() { exprs(unresolveElement(this),_,result) }
/** Holds if this is an auxiliary expression generated by the compiler. */ /** Holds if this is an auxiliary expression generated by the compiler. */
predicate isCompilerGenerated() { predicate isCompilerGenerated() {
compgenerated(this) or compgenerated(unresolveElement(this)) or
this.getParent().(ConstructorFieldInit).isCompilerGenerated() this.getParent().(ConstructorFieldInit).isCompilerGenerated()
} }
@@ -55,7 +55,7 @@ class Expr extends StmtParent, @expr {
* As the type of an expression can sometimes be a TypedefType, calling getUnderlyingType() * As the type of an expression can sometimes be a TypedefType, calling getUnderlyingType()
* is often more useful than calling this predicate. * is often more useful than calling this predicate.
*/ */
pragma[nomagic] Type getType() { expr_types(this,unresolve(result),_) } pragma[nomagic] Type getType() { expr_types(unresolveElement(this),unresolveElement(result),_) }
/** /**
* Gets the type of this expression after typedefs have been resolved. * Gets the type of this expression after typedefs have been resolved.
@@ -71,19 +71,19 @@ class Expr extends StmtParent, @expr {
* *
* Consider using subclasses of `Expr` rather than relying on this predicate. * Consider using subclasses of `Expr` rather than relying on this predicate.
*/ */
int getKind() { exprs(this,result,_) } int getKind() { exprs(unresolveElement(this),result,_) }
/** Gets a textual representation of this expression. */ /** Gets a textual representation of this expression. */
override string toString() { none() } override string toString() { none() }
/** Gets the value of this expression, if it is a constant. */ /** Gets the value of this expression, if it is a constant. */
string getValue() { exists(@value v | values(v,result,_) and valuebind(v,this)) } string getValue() { exists(@value v | values(v,result,_) and valuebind(v,unresolveElement(this))) }
/** Gets the source text for the value of this expression, if it is a constant. */ /** Gets the source text for the value of this expression, if it is a constant. */
string getValueText() { exists(@value v | values(v,_,result) and valuebind(v,this)) } string getValueText() { exists(@value v | values(v,_,result) and valuebind(v,unresolveElement(this))) }
/** Holds if this expression has a value that can be determined at compile time. */ /** Holds if this expression has a value that can be determined at compile time. */
predicate isConstant() { valuebind(_,this) } predicate isConstant() { valuebind(_,unresolveElement(this)) }
/** /**
* Holds if this expression is side-effect free (conservative * Holds if this expression is side-effect free (conservative
@@ -124,7 +124,7 @@ class Expr extends StmtParent, @expr {
* See [basic.lval] for more about lvalues. * See [basic.lval] for more about lvalues.
*/ */
predicate isLValueCategory() { predicate isLValueCategory() {
expr_types(this, _, 3) expr_types(unresolveElement(this), _, 3)
} }
/** /**
@@ -134,7 +134,7 @@ class Expr extends StmtParent, @expr {
* See [basic.lval] for more about xvalues. * See [basic.lval] for more about xvalues.
*/ */
predicate isXValueCategory() { predicate isXValueCategory() {
expr_types(this, _, 2) expr_types(unresolveElement(this), _, 2)
} }
/** /**
@@ -143,7 +143,7 @@ class Expr extends StmtParent, @expr {
* See [basic.lval] for more about prvalues. * See [basic.lval] for more about prvalues.
*/ */
predicate isPRValueCategory() { predicate isPRValueCategory() {
expr_types(this, _, 1) expr_types(unresolveElement(this), _, 1)
} }
/** /**
@@ -234,7 +234,7 @@ class Expr extends StmtParent, @expr {
* See [conv.lval] for more about the lvalue-to-rvalue conversion * See [conv.lval] for more about the lvalue-to-rvalue conversion
*/ */
predicate hasLValueToRValueConversion() { predicate hasLValueToRValueConversion() {
expr_isload(this) expr_isload(unresolveElement(this))
} }
/** /**
@@ -303,14 +303,14 @@ class Expr extends StmtParent, @expr {
* and 1 has a bool conversion, while the bool conversion itself has * and 1 has a bool conversion, while the bool conversion itself has
* an int conversion. * an int conversion.
*/ */
predicate hasConversion() { exists(Expr e | exprconv(this,e)) } predicate hasConversion() { exists(Expr e | exprconv(unresolveElement(this),unresolveElement(e))) }
/** /**
* Holds if this expression has an implicit conversion. * Holds if this expression has an implicit conversion.
* *
* For example in `char *str = 0`, the `0` has an implicit conversion to type `char *`. * For example in `char *str = 0`, the `0` has an implicit conversion to type `char *`.
*/ */
predicate hasImplicitConversion() { exists(Expr e | exprconv(this,e) and e.(Cast).isImplicit()) } predicate hasImplicitConversion() { exists(Expr e | exprconv(unresolveElement(this),unresolveElement(e)) and e.(Cast).isImplicit()) }
/** /**
* Holds if this expression has an explicit conversion. * Holds if this expression has an explicit conversion.
@@ -318,12 +318,12 @@ class Expr extends StmtParent, @expr {
* For example in `(MyClass *)ptr`, the `ptr` has an explicit * For example in `(MyClass *)ptr`, the `ptr` has an explicit
* conversion to type `MyClass *`. * conversion to type `MyClass *`.
*/ */
predicate hasExplicitConversion() { exists(Expr e | exprconv(this,e) and not e.(Cast).isImplicit()) } predicate hasExplicitConversion() { exists(Expr e | exprconv(unresolveElement(this),unresolveElement(e)) and not e.(Cast).isImplicit()) }
/** /**
* Gets the conversion associated with this expression, if any. * Gets the conversion associated with this expression, if any.
*/ */
Expr getConversion() { exprconv(this,result) } Expr getConversion() { exprconv(unresolveElement(this),unresolveElement(result)) }
/** /**
* Gets a string describing the conversion associated with this expression, * Gets a string describing the conversion associated with this expression,
@@ -594,14 +594,14 @@ class NewExpr extends Expr, @new_expr {
* For example, for `new int` the result is `int`. * For example, for `new int` the result is `int`.
*/ */
Type getAllocatedType() { Type getAllocatedType() {
new_allocated_type(this, unresolve(result)) new_allocated_type(unresolveElement(this), unresolveElement(result))
} }
/** /**
* Gets the `operator new` that allocates storage. * Gets the `operator new` that allocates storage.
*/ */
Function getAllocator() { Function getAllocator() {
expr_allocator(this, result, _) expr_allocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -609,7 +609,7 @@ class NewExpr extends Expr, @new_expr {
* argument of type `std::align_val_t`. * argument of type `std::align_val_t`.
*/ */
predicate hasAlignedAllocation() { predicate hasAlignedAllocation() {
expr_allocator(this, _, 1) expr_allocator(unresolveElement(this), _, 1)
} }
/** /**
@@ -629,7 +629,7 @@ class NewExpr extends Expr, @new_expr {
* throws an exception, if any. * throws an exception, if any.
*/ */
Function getDeallocator() { Function getDeallocator() {
expr_deallocator(this, result, _) expr_deallocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -637,7 +637,7 @@ class NewExpr extends Expr, @new_expr {
*/ */
predicate hasSizedDeallocation() { predicate hasSizedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(1) != 0 // Bit zero is the "size" bit form.bitAnd(1) != 0 // Bit zero is the "size" bit
) )
} }
@@ -647,7 +647,7 @@ class NewExpr extends Expr, @new_expr {
*/ */
predicate hasAlignedDeallocation() { predicate hasAlignedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(2) != 0 // Bit one is the "alignment" bit form.bitAnd(2) != 0 // Bit one is the "alignment" bit
) )
} }
@@ -675,7 +675,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
* For example, for `new int[5]` the result is `int[5]`. * For example, for `new int[5]` the result is `int[5]`.
*/ */
Type getAllocatedType() { Type getAllocatedType() {
new_array_allocated_type(this, unresolve(result)) new_array_allocated_type(unresolveElement(this), unresolveElement(result))
} }
/** /**
@@ -689,7 +689,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
* Gets the `operator new[]` that allocates storage. * Gets the `operator new[]` that allocates storage.
*/ */
Function getAllocator() { Function getAllocator() {
expr_allocator(this, result, _) expr_allocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -697,7 +697,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
* argument of type `std::align_val_t`. * argument of type `std::align_val_t`.
*/ */
predicate hasAlignedAllocation() { predicate hasAlignedAllocation() {
expr_allocator(this, _, 1) expr_allocator(unresolveElement(this), _, 1)
} }
/** /**
@@ -712,7 +712,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
* throws an exception, if any. * throws an exception, if any.
*/ */
Function getDeallocator() { Function getDeallocator() {
expr_deallocator(this, result, _) expr_deallocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -720,7 +720,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
*/ */
predicate hasSizedDeallocation() { predicate hasSizedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(1) != 0 // Bit zero is the "size" bit form.bitAnd(1) != 0 // Bit zero is the "size" bit
) )
} }
@@ -730,7 +730,7 @@ class NewArrayExpr extends Expr, @new_array_expr {
*/ */
predicate hasAlignedDeallocation() { predicate hasAlignedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(2) != 0 // Bit one is the "alignment" bit form.bitAnd(2) != 0 // Bit one is the "alignment" bit
) )
} }
@@ -788,7 +788,7 @@ class DeleteExpr extends Expr, @delete_expr {
* dynamic type of the object. * dynamic type of the object.
*/ */
Function getDeallocator() { Function getDeallocator() {
expr_deallocator(this, result, _) expr_deallocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -796,7 +796,7 @@ class DeleteExpr extends Expr, @delete_expr {
*/ */
predicate hasSizedDeallocation() { predicate hasSizedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(1) != 0 // Bit zero is the "size" bit form.bitAnd(1) != 0 // Bit zero is the "size" bit
) )
} }
@@ -806,7 +806,7 @@ class DeleteExpr extends Expr, @delete_expr {
*/ */
predicate hasAlignedDeallocation() { predicate hasAlignedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(2) != 0 // Bit one is the "alignment" bit form.bitAnd(2) != 0 // Bit one is the "alignment" bit
) )
} }
@@ -856,7 +856,7 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
* Gets the `operator delete[]` that deallocates storage. * Gets the `operator delete[]` that deallocates storage.
*/ */
Function getDeallocator() { Function getDeallocator() {
expr_deallocator(this, result, _) expr_deallocator(unresolveElement(this), unresolveElement(result), _)
} }
/** /**
@@ -864,7 +864,7 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
*/ */
predicate hasSizedDeallocation() { predicate hasSizedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(1) != 0 // Bit zero is the "size" bit form.bitAnd(1) != 0 // Bit zero is the "size" bit
) )
} }
@@ -874,7 +874,7 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
*/ */
predicate hasAlignedDeallocation() { predicate hasAlignedDeallocation() {
exists(int form | exists(int form |
expr_deallocator(this, _, form) and expr_deallocator(unresolveElement(this), _, form) and
form.bitAnd(2) != 0 // Bit one is the "alignment" bit form.bitAnd(2) != 0 // Bit one is the "alignment" bit
) )
} }
@@ -944,7 +944,7 @@ class ThisExpr extends Expr, @thisaccess {
*/ */
class BlockExpr extends Literal { class BlockExpr extends Literal {
BlockExpr() { BlockExpr() {
code_block(this, _) code_block(unresolveElement(this), _)
} }
override string toString() { result = "^ { ... }" } override string toString() { result = "^ { ... }" }
@@ -953,7 +953,7 @@ class BlockExpr extends Literal {
* Gets the (anonymous) function associated with this code block expression. * Gets the (anonymous) function associated with this code block expression.
*/ */
Function getFunction() { Function getFunction() {
code_block(this, result) code_block(unresolveElement(this), unresolveElement(result))
} }
} }
@@ -980,7 +980,7 @@ private predicate convparents(Expr child, int idx, Element parent) {
idx = 0 idx = 0
or or
exists(Expr astChild | exists(Expr astChild |
exprparents(astChild, idx, parent) and exprparents(unresolveElement(astChild), idx, unresolveElement(parent)) and
child = astChild.getFullyConverted() child = astChild.getFullyConverted()
) )
} }

View File

@@ -22,7 +22,7 @@ class LambdaExpression extends Expr, @lambdaexpr {
* Gets the nth implicitly or explicitly captured value of this lambda expression. * Gets the nth implicitly or explicitly captured value of this lambda expression.
*/ */
LambdaCapture getCapture(int index) { LambdaCapture getCapture(int index) {
lambda_capture(result, this, index, _, _, _) lambda_capture(result, unresolveElement(this), index, _, _, _)
} }
/** /**
@@ -34,14 +34,14 @@ class LambdaExpression extends Expr, @lambdaexpr {
* - "=" if capture-by-value is the default for implicit captures. * - "=" if capture-by-value is the default for implicit captures.
*/ */
string getDefaultCaptureMode() { string getDefaultCaptureMode() {
lambdas(this, result, _) lambdas(unresolveElement(this), result, _)
} }
/** /**
* Holds if the return type (of the call operator of the resulting object) was explicitly specified. * Holds if the return type (of the call operator of the resulting object) was explicitly specified.
*/ */
predicate returnTypeIsExplicit() { predicate returnTypeIsExplicit() {
lambdas(this, _, true) lambdas(unresolveElement(this), _, true)
} }
/** /**

View File

@@ -36,12 +36,12 @@ class Literal extends Expr, @literal {
*/ */
class LabelLiteral extends Literal { class LabelLiteral extends Literal {
LabelLiteral() { LabelLiteral() {
jumpinfo(this,_,_) jumpinfo(unresolveElement(this),_,_)
} }
/** Gets the corresponding label statement. */ /** Gets the corresponding label statement. */
LabelStmt getLabel() { LabelStmt getLabel() {
jumpinfo(this,_,result) jumpinfo(unresolveElement(this),_,unresolveElement(result))
} }
} }

View File

@@ -41,15 +41,6 @@ cached private module Cached {
(not hasCompleteTwin(c, _) and result = c) (not hasCompleteTwin(c, _) and result = c)
} }
/**
* Gets a type from the database for which `t` is a complete definition.
*/
cached @type unresolve(Type t) {
if isClass(t)
then resolve(result) = t
else result = t
}
/** /**
* Holds if `t` is a struct, class, union, or template. * Holds if `t` is a struct, class, union, or template.
*/ */

View File

@@ -432,7 +432,7 @@ predicate dependsOnClassSimple(Class source, Class dest) {
// a class depends on the types of its member variables // a class depends on the types of its member variables
or exists(MemberVariable v, Type t | v.getDeclaringType() = source and v.getType() = t and t.refersTo(dest)) or exists(MemberVariable v, Type t | v.getDeclaringType() = source and v.getType() = t and t.refersTo(dest) and v instanceof MemberVariable)
// a class depends on the return types of its member functions // a class depends on the return types of its member functions
or exists(MemberFunction f, Type t | f.getDeclaringType() = source and f instanceof MemberFunction and f.getType() = t and t.refersTo(dest)) or exists(MemberFunction f, Type t | f.getDeclaringType() = source and f instanceof MemberFunction and f.getType() = t and t.refersTo(dest))
@@ -471,7 +471,8 @@ predicate dependsOnClassSimple(Class source, Class dest) {
and fa.getEnclosingFunction() = f and fa.getEnclosingFunction() = f
and fa.getTarget() = mf and fa.getTarget() = mf
and mf.getDeclaringType() = dest and mf.getDeclaringType() = dest
and mf instanceof MemberFunction) and mf instanceof MemberFunction
and fa instanceof FunctionAccess)
// a class depends on classes for which its member functions are accessed from a member variable initializer // a class depends on classes for which its member functions are accessed from a member variable initializer
or exists(MemberVariable v, FunctionAccess fa, MemberFunction mf | or exists(MemberVariable v, FunctionAccess fa, MemberFunction mf |
@@ -480,6 +481,7 @@ predicate dependsOnClassSimple(Class source, Class dest) {
and fa.getEnclosingVariable() = v and fa.getEnclosingVariable() = v
and fa.getTarget() = mf and fa.getTarget() = mf
and mf.getDeclaringType() = dest and mf.getDeclaringType() = dest
and fa instanceof FunctionAccess
and mf instanceof MemberFunction) and mf instanceof MemberFunction)
// a class depends on classes for which its member variables are accessed from a member function // a class depends on classes for which its member variables are accessed from a member function

View File

@@ -22,17 +22,17 @@ class MetricFile extends File {
/** Gets the number of lines in this file. */ /** Gets the number of lines in this file. */
int getNumberOfLines() { int getNumberOfLines() {
numlines(this,result,_,_) numlines(unresolveElement(this),result,_,_)
} }
/** Gets the number of lines of code in this file. */ /** Gets the number of lines of code in this file. */
int getNumberOfLinesOfCode() { int getNumberOfLinesOfCode() {
numlines(this,_,result,_) numlines(unresolveElement(this),_,result,_)
} }
/** Gets the number of lines of comments in this file. */ /** Gets the number of lines of comments in this file. */
int getNumberOfLinesOfComments() { int getNumberOfLinesOfComments() {
numlines(this,_,_,result) numlines(unresolveElement(this),_,_,result)
} }
/** Gets the number of incoming file dependencies. */ /** Gets the number of incoming file dependencies. */

View File

@@ -12,17 +12,17 @@ class MetricFunction extends Function {
/** Gets the number of lines in this function. */ /** Gets the number of lines in this function. */
int getNumberOfLines() { int getNumberOfLines() {
numlines(this,result,_,_) numlines(unresolveElement(this),result,_,_)
} }
/** Gets the number of lines of code in this function. */ /** Gets the number of lines of code in this function. */
int getNumberOfLinesOfCode() { int getNumberOfLinesOfCode() {
numlines(this,_,result,_) numlines(unresolveElement(this),_,result,_)
} }
/** Gets the number of lines of comments in this function. */ /** Gets the number of lines of comments in this function. */
int getNumberOfLinesOfComments() { int getNumberOfLinesOfComments() {
numlines(this,_,_,result) numlines(unresolveElement(this),_,_,result)
} }
/** Gets the ratio of lines of comments to total lines in this function (between 0.0 and 1.0). */ /** Gets the ratio of lines of comments to total lines in this function (between 0.0 and 1.0). */

View File

@@ -16,14 +16,14 @@ class TargetPointsToExpr extends PointsToExpr {
// resolve a virtual-call where this is the qualifier // resolve a virtual-call where this is the qualifier
VirtualFunction resolve() VirtualFunction resolve()
{ {
pointstosets(this.resolveToSet(), result) pointstosets(this.resolveToSet(), unresolveElement(result))
} }
int resolveToSet() int resolveToSet()
{ {
exists(int cset, VirtualFunction static | exists(int cset, VirtualFunction static |
this.interesting() and this.interesting() and
parentSetFor(cset, this) and parentSetFor(cset, unresolveElement(this)) and
static = this.staticTarget() and static = this.staticTarget() and
childrenByElement(cset, static, result) childrenByElement(cset, static, result)
) )

View File

@@ -61,7 +61,7 @@ predicate lvalue(Element e) {
or or
e.(Expr).getConversion() instanceof ArrayToPointerConversion e.(Expr).getConversion() instanceof ArrayToPointerConversion
or or
exists(ParenthesisExpr paren | exprconv(e, paren) and lvalue(paren)) exists(ParenthesisExpr paren | exprconv(unresolveElement(e), unresolveElement(paren)) and lvalue(paren))
or or
exists(Cast c | lvalue(c) and e.(Expr).getConversion() = c) exists(Cast c | lvalue(c) and e.(Expr).getConversion() = c)
or or
@@ -127,6 +127,10 @@ predicate pointerValue(Expr e) {
t instanceof ReferenceType)) t instanceof ReferenceType))
} }
private predicate pointerEntity(@element src, @element dest) {
pointer(mkElement(src), mkElement(dest))
}
/** /**
* The source is a pointer to the destination. * The source is a pointer to the destination.
*/ */
@@ -157,7 +161,7 @@ predicate pointer(Element src, Element dest)
src = ae.getArrayOffset().getFullyConverted() and pointerValue(src)) src = ae.getArrayOffset().getFullyConverted() and pointerValue(src))
or or
exists(ReferenceDereferenceExpr deref | not(lvalue(deref)) and exists(ReferenceDereferenceExpr deref | not(lvalue(deref)) and
dest = deref and exprconv(src, deref)) dest = deref and exprconv(unresolveElement(src), unresolveElement(deref)))
or or
exists(AggregateLiteral agg | not(lvalue(dest)) and exists(AggregateLiteral agg | not(lvalue(dest)) and
agg.getType().getUnderlyingType() instanceof ArrayType and agg.getType().getUnderlyingType() instanceof ArrayType and
@@ -174,6 +178,10 @@ predicate pointer(Element src, Element dest)
// //
} }
private predicate flowEntity(@element src, @element dest) {
flow(mkElement(src), mkElement(dest))
}
/** /**
* The value held in the source flows to the value held in the destination. * The value held in the source flows to the value held in the destination.
*/ */
@@ -224,17 +232,17 @@ predicate flow(Element src, Element dest)
or or
exists(Cast c | src = c.getExpr() and dest = c) exists(Cast c | src = c.getExpr() and dest = c)
or or
exists(ReferenceToExpr toref | exprconv(src, toref) and dest = toref) exists(ReferenceToExpr toref | exprconv(unresolveElement(src), unresolveElement(toref)) and dest = toref)
or or
exists(ReferenceDereferenceExpr deref | lvalue(deref) and exists(ReferenceDereferenceExpr deref | lvalue(deref) and
dest = deref and exprconv(src, deref)) dest = deref and exprconv(unresolveElement(src), unresolveElement(deref)))
or or
exists(ArrayToPointerConversion conv | exprconv(src, conv) and dest = conv) exists(ArrayToPointerConversion conv | exprconv(unresolveElement(src), unresolveElement(conv)) and dest = conv)
or or
exists(ParenthesisExpr paren | exists(ParenthesisExpr paren |
// these can appear on the LHS of an assignment // these can appear on the LHS of an assignment
(exprconv(src, paren) and dest = paren) or (exprconv(unresolveElement(src), unresolveElement(paren)) and dest = paren) or
(exprconv(dest, paren) and src = paren)) (exprconv(unresolveElement(dest), unresolveElement(paren)) and src = paren))
or or
exists(ConditionalExpr cond | dest = cond and exists(ConditionalExpr cond | dest = cond and
( src = cond.getThen().getFullyConverted() or ( src = cond.getThen().getFullyConverted() or
@@ -249,7 +257,7 @@ predicate flow(Element src, Element dest)
exists(CommaExpr comma | dest = comma and exists(CommaExpr comma | dest = comma and
src = comma.getRightOperand().getFullyConverted()) src = comma.getRightOperand().getFullyConverted())
or or
exists(ParenthesisExpr paren | dest = paren and exprconv(src, paren)) exists(ParenthesisExpr paren | dest = paren and exprconv(unresolveElement(src), unresolveElement(paren)))
or or
// "vtable" for new-expressions // "vtable" for new-expressions
exists(NewExpr new | src = new and dest = new.getAllocatedType()) exists(NewExpr new | src = new and dest = new.getAllocatedType())
@@ -437,6 +445,10 @@ predicate virtualRet(Expr receiver, VirtualFunction called, string retlabel, Fun
and called.isVirtual() and retlabel = "+ret" and called.isVirtual() and retlabel = "+ret"
} }
private predicate compoundEdgeEntity(@element parent, @element element, string label, @element other, int kind) {
compoundEdge(mkElement(parent), mkElement(element), label, mkElement(other), kind)
}
/** /**
* This relation combines all pointer and flow relations that * This relation combines all pointer and flow relations that
* go to or from a compound set. * go to or from a compound set.
@@ -504,7 +516,7 @@ predicate compoundEdge(Element parent, Element element, string label, Element ot
*/ */
cached cached
predicate pointstoinfo(int parent, @element elem, string label, int ptset) = predicate pointstoinfo(int parent, @element elem, string label, int ptset) =
collapse(flow/2, pointer/2, compoundEdge/5, location/1)(parent, elem, label, ptset) collapse(flowEntity/2, pointerEntity/2, compoundEdgeEntity/5, locationEntity/1)(parent, elem, label, ptset)
/** /**
* Which elements are in which points-to sets. * Which elements are in which points-to sets.
@@ -539,7 +551,7 @@ predicate children(int parentset, string label, int childset)
*/ */
predicate childrenByElement(int parentset, Element label, int childset) predicate childrenByElement(int parentset, Element label, int childset)
{ {
pointstoinfo(parentset, label, "--element--", childset) pointstoinfo(parentset, unresolveElement(label), "--element--", childset)
} }
/** /**
@@ -553,6 +565,10 @@ predicate parentSetFor(int cset, @element expr)
exists(string s | s = "" and pointstoinfo(cset, expr, s, _)) exists(string s | s = "" and pointstoinfo(cset, expr, s, _))
} }
private predicate locationEntity(@element location) {
location(mkElement(location))
}
/** /**
* Things that are elements of points-to sets. * Things that are elements of points-to sets.
*/ */
@@ -583,7 +599,7 @@ private int interestingSet()
{ {
exists(PointsToExpr e | exists(PointsToExpr e |
e.interesting() and e.interesting() and
pointstosets(result, e) pointstosets(result, unresolveElement(e))
) or ( ) or (
setflow(result, interestingSet()) setflow(result, interestingSet())
) )
@@ -600,7 +616,7 @@ predicate setlocations(int set, @element location)
set = interestingSet() and set = interestingSet() and
( (
( (
location(location) and pointstosets(set, location) location(mkElement(location)) and pointstosets(set, location)
) or ) or
exists(int middle | setlocations(middle, location) and setflow(middle, set)) exists(int middle | setlocations(middle, location) and setflow(middle, set))
) )
@@ -617,7 +633,7 @@ class PointsToExpr extends Expr
pragma[noopt] pragma[noopt]
Element pointsTo() Element pointsTo()
{ {
this.interesting() and exists(int set | pointstosets(set, this) and setlocations(set, result)) this.interesting() and exists(int set, @element thisEntity, @element resultEntity | thisEntity = unresolveElement(this) and pointstosets(set, thisEntity) and setlocations(set, resultEntity) and resultEntity = unresolveElement(result))
} }
float confidence() { result = 1.0 / count(this.pointsTo()) } float confidence() { result = 1.0 / count(this.pointsTo()) }
@@ -631,6 +647,6 @@ class PointsToExpr extends Expr
*/ */
predicate anythingPointsTo(Element elem) predicate anythingPointsTo(Element elem)
{ {
location(elem) and pointstosets(interestingSet(), elem) location(elem) and pointstosets(interestingSet(), unresolveElement(elem))
} }

View File

@@ -52,9 +52,9 @@ private predicate guardCondition(
} }
private predicate guardSuccessor(ComparisonOperation guard, boolean branch, BasicBlock succ) { private predicate guardSuccessor(ComparisonOperation guard, boolean branch, BasicBlock succ) {
(branch = true and succ = guard.getATrueSuccessor()) (branch = true and mkElement(succ) = guard.getATrueSuccessor())
or or
(branch = false and succ = guard.getAFalseSuccessor()) (branch = false and mkElement(succ) = guard.getAFalseSuccessor())
} }
/** /**
@@ -67,7 +67,7 @@ private predicate guardSuccessor(ComparisonOperation guard, boolean branch, Basi
class RangeSsaDefinition extends @cfgnode { class RangeSsaDefinition extends @cfgnode {
RangeSsaDefinition() { RangeSsaDefinition() {
exists(RangeSSA x | x.ssa_defn(_, (ControlFlowNode)this, _, _)) exists(RangeSSA x | x.ssa_defn(_, (ControlFlowNode)mkElement(this), _, _))
} }
/** /**
@@ -75,7 +75,7 @@ class RangeSsaDefinition extends @cfgnode {
* this definition. * this definition.
*/ */
LocalScopeVariable getAVariable() { LocalScopeVariable getAVariable() {
exists(RangeSSA x | x.ssa_defn(result, (ControlFlowNode)this, _, _)) exists(RangeSSA x | x.ssa_defn(result, (ControlFlowNode)mkElement(this), _, _))
} }
string toString() { string toString() {
@@ -87,17 +87,17 @@ class RangeSsaDefinition extends @cfgnode {
* (this, v). * (this, v).
*/ */
string toString(LocalScopeVariable v) { string toString(LocalScopeVariable v) {
exists(RangeSSA x | result = x.toString((ControlFlowNode)this, v)) exists(RangeSSA x | result = x.toString((ControlFlowNode)mkElement(this), v))
} }
/** Gets a use of the SSA variable represented by the pair (this, v) */ /** Gets a use of the SSA variable represented by the pair (this, v) */
VariableAccess getAUse(LocalScopeVariable v) { VariableAccess getAUse(LocalScopeVariable v) {
exists(RangeSSA x | result = x.getAUse((ControlFlowNode)this, v)) exists(RangeSSA x | result = x.getAUse((ControlFlowNode)mkElement(this), v))
} }
/** Gets the control flow node for this definition */ /** Gets the control flow node for this definition */
ControlFlowNode getDefinition() { ControlFlowNode getDefinition() {
result = this result = mkElement(this)
} }
BasicBlock getBasicBlock() { BasicBlock getBasicBlock() {
@@ -118,12 +118,12 @@ class RangeSsaDefinition extends @cfgnode {
} }
Location getLocation() { Location getLocation() {
result = this.(ControlFlowNode).getLocation() result = mkElement(this).(ControlFlowNode).getLocation()
} }
/** Whether this definition is from a parameter */ /** Whether this definition is from a parameter */
predicate definedByParameter(Parameter p) { predicate definedByParameter(Parameter p) {
this = p.getFunction().getEntryPoint() mkElement(this) = p.getFunction().getEntryPoint()
} }
RangeSsaDefinition getAPhiInput(LocalScopeVariable v) { RangeSsaDefinition getAPhiInput(LocalScopeVariable v) {
@@ -174,6 +174,6 @@ class RangeSsaDefinition extends @cfgnode {
} }
predicate reachesEndOfBB(LocalScopeVariable v, BasicBlock b) { predicate reachesEndOfBB(LocalScopeVariable v, BasicBlock b) {
exists(RangeSSA x | x.ssaDefinitionReachesEndOfBB(v, (ControlFlowNode)this, b)) exists(RangeSSA x | x.ssaDefinitionReachesEndOfBB(v, (ControlFlowNode)mkElement(this), b))
} }
} }

View File

@@ -144,20 +144,20 @@ predicate defDependsOnDef(
or or
exists ( exists (
AssignAddExpr assignAdd, RangeSsaDefinition nextDef AssignAddExpr assignAdd, RangeSsaDefinition nextDef
| def = assignAdd and | mkElement(def) = assignAdd and
assignAdd.getLValue() = nextDef.getAUse(v) assignAdd.getLValue() = nextDef.getAUse(v)
| defDependsOnDef(nextDef, v, srcDef, srcVar) or | defDependsOnDef(nextDef, v, srcDef, srcVar) or
exprDependsOnDef(assignAdd.getRValue(), srcDef, srcVar)) exprDependsOnDef(assignAdd.getRValue(), srcDef, srcVar))
or or
exists ( exists (
AssignSubExpr assignSub, RangeSsaDefinition nextDef AssignSubExpr assignSub, RangeSsaDefinition nextDef
| def = assignSub and | mkElement(def) = assignSub and
assignSub.getLValue() = nextDef.getAUse(v) assignSub.getLValue() = nextDef.getAUse(v)
| defDependsOnDef(nextDef, v, srcDef, srcVar) or | defDependsOnDef(nextDef, v, srcDef, srcVar) or
exprDependsOnDef(assignSub.getRValue(), srcDef, srcVar)) exprDependsOnDef(assignSub.getRValue(), srcDef, srcVar))
or or
exists (CrementOperation crem exists (CrementOperation crem
| def = crem and | mkElement(def) = crem and
crem.getOperand() = v.getAnAccess() and crem.getOperand() = v.getAnAccess() and
exprDependsOnDef(crem.getOperand(), srcDef, srcVar)) exprDependsOnDef(crem.getOperand(), srcDef, srcVar))
or or
@@ -278,10 +278,10 @@ private
predicate assignmentDef(RangeSsaDefinition def, LocalScopeVariable v, Expr expr) { predicate assignmentDef(RangeSsaDefinition def, LocalScopeVariable v, Expr expr) {
v.getType().getUnspecifiedType() instanceof ArithmeticType v.getType().getUnspecifiedType() instanceof ArithmeticType
and and
((def = v.getInitializer().getExpr() and def = expr) ((mkElement(def) = v.getInitializer().getExpr() and mkElement(def) = expr)
or or
exists(AssignExpr assign exists(AssignExpr assign
| def = assign and | mkElement(def) = assign and
assign.getLValue() = v.getAnAccess() and assign.getLValue() = v.getAnAccess() and
expr = assign.getRValue())) expr = assign.getRValue()))
} }
@@ -845,7 +845,7 @@ float getDefLowerBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
or or
exists ( exists (
AssignAddExpr assignAdd, RangeSsaDefinition nextDef, float lhsLB, float rhsLB AssignAddExpr assignAdd, RangeSsaDefinition nextDef, float lhsLB, float rhsLB
| def = assignAdd and | mkElement(def) = assignAdd and
assignAdd.getLValue() = nextDef.getAUse(v) and assignAdd.getLValue() = nextDef.getAUse(v) and
lhsLB = getDefLowerBounds(nextDef, v) and lhsLB = getDefLowerBounds(nextDef, v) and
rhsLB = getFullyConvertedLowerBounds(assignAdd.getRValue()) and rhsLB = getFullyConvertedLowerBounds(assignAdd.getRValue()) and
@@ -853,20 +853,20 @@ float getDefLowerBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
or or
exists ( exists (
AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsLB, float rhsUB AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsLB, float rhsUB
| def = assignSub and | mkElement(def) = assignSub and
assignSub.getLValue() = nextDef.getAUse(v) and assignSub.getLValue() = nextDef.getAUse(v) and
lhsLB = getDefLowerBounds(nextDef, v) and lhsLB = getDefLowerBounds(nextDef, v) and
rhsUB = getFullyConvertedUpperBounds(assignSub.getRValue()) and rhsUB = getFullyConvertedUpperBounds(assignSub.getRValue()) and
result = lhsLB - rhsUB) result = lhsLB - rhsUB)
or or
exists (IncrementOperation incr, float newLB exists (IncrementOperation incr, float newLB
| def = incr and | mkElement(def) = incr and
incr.getOperand() = v.getAnAccess() and incr.getOperand() = v.getAnAccess() and
newLB = getFullyConvertedLowerBounds(incr.getOperand()) and newLB = getFullyConvertedLowerBounds(incr.getOperand()) and
result = newLB+1) result = newLB+1)
or or
exists (DecrementOperation decr, float newLB exists (DecrementOperation decr, float newLB
| def = decr and | mkElement(def) = decr and
decr.getOperand() = v.getAnAccess() and decr.getOperand() = v.getAnAccess() and
newLB = getFullyConvertedLowerBounds(decr.getOperand()) and newLB = getFullyConvertedLowerBounds(decr.getOperand()) and
result = newLB-1) result = newLB-1)
@@ -888,7 +888,7 @@ float getDefUpperBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
or or
exists ( exists (
AssignAddExpr assignAdd, RangeSsaDefinition nextDef, float lhsUB, float rhsUB AssignAddExpr assignAdd, RangeSsaDefinition nextDef, float lhsUB, float rhsUB
| def = assignAdd and | mkElement(def) = assignAdd and
assignAdd.getLValue() = nextDef.getAUse(v) and assignAdd.getLValue() = nextDef.getAUse(v) and
lhsUB = getDefUpperBounds(nextDef, v) and lhsUB = getDefUpperBounds(nextDef, v) and
rhsUB = getFullyConvertedUpperBounds(assignAdd.getRValue()) and rhsUB = getFullyConvertedUpperBounds(assignAdd.getRValue()) and
@@ -896,20 +896,20 @@ float getDefUpperBoundsImpl(RangeSsaDefinition def, LocalScopeVariable v) {
or or
exists ( exists (
AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsUB, float rhsLB AssignSubExpr assignSub, RangeSsaDefinition nextDef, float lhsUB, float rhsLB
| def = assignSub and | mkElement(def) = assignSub and
assignSub.getLValue() = nextDef.getAUse(v) and assignSub.getLValue() = nextDef.getAUse(v) and
lhsUB = getDefUpperBounds(nextDef, v) and lhsUB = getDefUpperBounds(nextDef, v) and
rhsLB = getFullyConvertedLowerBounds(assignSub.getRValue()) and rhsLB = getFullyConvertedLowerBounds(assignSub.getRValue()) and
result = lhsUB - rhsLB) result = lhsUB - rhsLB)
or or
exists (IncrementOperation incr, float newUB exists (IncrementOperation incr, float newUB
| def = incr and | mkElement(def) = incr and
incr.getOperand() = v.getAnAccess() and incr.getOperand() = v.getAnAccess() and
newUB = getFullyConvertedUpperBounds(incr.getOperand()) and newUB = getFullyConvertedUpperBounds(incr.getOperand()) and
result = newUB+1) result = newUB+1)
or or
exists (DecrementOperation decr, float newUB exists (DecrementOperation decr, float newUB
| def = decr and | mkElement(def) = decr and
decr.getOperand() = v.getAnAccess() and decr.getOperand() = v.getAnAccess() and
newUB = getFullyConvertedUpperBounds(decr.getOperand()) and newUB = getFullyConvertedUpperBounds(decr.getOperand()) and
result = newUB-1) result = newUB-1)

View File

@@ -521,12 +521,12 @@ private predicate methodReturningReceiver(MemberFunction method) {
Function resolveCall(Call call) { Function resolveCall(Call call) {
result = call.getTarget() result = call.getTarget()
or or
result = call.(DataSensitiveCallExpr).resolve() result = unresolveElement(call).(DataSensitiveCallExpr).resolve()
} }
/** A data sensitive call expression. */ /** A data sensitive call expression. */
library abstract class DataSensitiveCallExpr extends @expr { library abstract class DataSensitiveCallExpr extends @expr {
DataSensitiveCallExpr() { not unreachable(this) } DataSensitiveCallExpr() { not unreachable(mkElement(this)) }
abstract Expr getSrc(); abstract Expr getSrc();
cached abstract Function resolve(); cached abstract Function resolve();
@@ -556,23 +556,27 @@ library abstract class DataSensitiveCallExpr extends @expr {
} }
/** Call through a function pointer. */ /** Call through a function pointer. */
library class DataSensitiveExprCall extends DataSensitiveCallExpr, ExprCall { library class DataSensitiveExprCall extends DataSensitiveCallExpr {
override Expr getSrc() { result = getExpr() } DataSensitiveExprCall() {
mkElement(this) instanceof ExprCall
}
override Expr getSrc() { result = mkElement(this).(ExprCall).getExpr() }
override Function resolve() { override Function resolve() {
exists(FunctionAccess fa | flowsFrom(fa, true) | result = fa.getTarget()) exists(FunctionAccess fa | flowsFrom(fa, true) | result = fa.getTarget())
} }
override string toString() { result = ExprCall.super.toString() } override string toString() { result = mkElement(this).toString() }
} }
/** Call to a virtual function. */ /** Call to a virtual function. */
library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr, FunctionCall { library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr {
DataSensitiveOverriddenFunctionCall() { DataSensitiveOverriddenFunctionCall() {
exists(getTarget().(VirtualFunction).getAnOverridingFunction()) exists(mkElement(this).(FunctionCall).getTarget().(VirtualFunction).getAnOverridingFunction())
} }
override Expr getSrc() { result = getQualifier() } override Expr getSrc() { result = mkElement(this).(FunctionCall).getQualifier() }
override MemberFunction resolve() { override MemberFunction resolve() {
exists(NewExpr new | exists(NewExpr new |
@@ -580,11 +584,11 @@ library class DataSensitiveOverriddenFunctionCall extends DataSensitiveCallExpr,
and and
memberFunctionFromNewExpr(new, result) memberFunctionFromNewExpr(new, result)
and and
result.overrides*(getTarget().(VirtualFunction)) result.overrides*(mkElement(this).(FunctionCall).getTarget().(VirtualFunction))
) )
} }
override string toString() { result = FunctionCall.super.toString() } override string toString() { result = mkElement(this).toString() }
} }
private predicate memberFunctionFromNewExpr(NewExpr new, MemberFunction f) { private predicate memberFunctionFromNewExpr(NewExpr new, MemberFunction f) {

View File

@@ -9,8 +9,8 @@ class Stmt extends StmtParent, @stmt {
/** Gets the `n`th child of this statement. */ /** Gets the `n`th child of this statement. */
Element getChild(int n) { Element getChild(int n) {
stmtparents(result,n,this) or stmtparents(unresolveElement(result),n,unresolveElement(this)) or
exprparents(result,n,this) exprparents(unresolveElement(result),n,unresolveElement(this))
} }
/** Holds if `e` is the `n`th child of this statement. */ /** Holds if `e` is the `n`th child of this statement. */
@@ -35,10 +35,10 @@ class Stmt extends StmtParent, @stmt {
Element getAChild() { exists (int n | result = this.getChild(n)) } Element getAChild() { exists (int n | result = this.getChild(n)) }
/** Gets the parent of this statement, if any. */ /** Gets the parent of this statement, if any. */
StmtParent getParent() { stmtparents(this,_,result) } StmtParent getParent() { stmtparents(unresolveElement(this),_,unresolveElement(result)) }
/** Gets the parent statement of this statement, if any. */ /** Gets the parent statement of this statement, if any. */
Stmt getParentStmt() { stmtparents(this,_,result) } Stmt getParentStmt() { stmtparents(unresolveElement(this),_,unresolveElement(result)) }
/** Gets a child statement of this statement. */ /** Gets a child statement of this statement. */
Stmt getChildStmt() { result.getParentStmt() = this } Stmt getChildStmt() { result.getParentStmt() = this }
@@ -51,10 +51,10 @@ class Stmt extends StmtParent, @stmt {
result = b.getStmt(i+1)) result = b.getStmt(i+1))
} }
override Location getLocation() { stmts(this,_,result) } override Location getLocation() { stmts(unresolveElement(this),_,result) }
/** Gets an int indicating the type of statement that this represents. */ /** Gets an int indicating the type of statement that this represents. */
int getKind() { stmts(this,result,_) } int getKind() { stmts(unresolveElement(this),result,_) }
override string toString() { none() } override string toString() { none() }
@@ -108,7 +108,7 @@ class Stmt extends StmtParent, @stmt {
* `[[clang::fallthrough]]`. * `[[clang::fallthrough]]`.
*/ */
Attribute getAnAttribute() { Attribute getAnAttribute() {
stmtattributes(this, result) stmtattributes(unresolveElement(this), unresolveElement(result))
} }
/** /**
@@ -135,7 +135,7 @@ class Stmt extends StmtParent, @stmt {
/** Holds if this statement was generated by the compiler. */ /** Holds if this statement was generated by the compiler. */
predicate isCompilerGenerated() { predicate isCompilerGenerated() {
compgenerated(this) compgenerated(unresolveElement(this))
} }
} }
@@ -233,7 +233,7 @@ class IfStmt extends ConditionalStmt, @stmt_if {
* ``` * ```
* the result is the `Block` `{ x = 1; }`. * the result is the `Block` `{ x = 1; }`.
*/ */
Stmt getThen() { if_then(this, result) } Stmt getThen() { if_then(unresolveElement(this), unresolveElement(result)) }
/** /**
* Gets the 'else' statement of this 'if' statement, if any. * Gets the 'else' statement of this 'if' statement, if any.
@@ -248,7 +248,7 @@ class IfStmt extends ConditionalStmt, @stmt_if {
* ``` * ```
* there is no result. * there is no result.
*/ */
Stmt getElse() { if_else(this, result) } Stmt getElse() { if_else(unresolveElement(this), unresolveElement(result)) }
/** /**
* Holds if this 'if' statement has an 'else' statement. * Holds if this 'if' statement has an 'else' statement.
@@ -306,7 +306,7 @@ abstract class Loop extends ControlStructure {
class WhileStmt extends Loop, @stmt_while { class WhileStmt extends Loop, @stmt_while {
override Expr getCondition() { result = this.getChild(0) } override Expr getCondition() { result = this.getChild(0) }
override Expr getControllingExpr() { result = this.getCondition() } override Expr getControllingExpr() { result = this.getCondition() }
override Stmt getStmt() { while_body(this, result) } override Stmt getStmt() { while_body(unresolveElement(this), unresolveElement(result)) }
override string toString() { result = "while (...) ..." } override string toString() { result = "while (...) ..." }
@@ -371,7 +371,7 @@ class WhileStmt extends Loop, @stmt_while {
abstract class JumpStmt extends Stmt, @jump { abstract class JumpStmt extends Stmt, @jump {
/** Gets the target of this jump statement. */ /** Gets the target of this jump statement. */
Stmt getTarget() { jumpinfo(this,_,result) } Stmt getTarget() { jumpinfo(unresolveElement(this),_,unresolveElement(result)) }
} }
/** /**
@@ -393,10 +393,10 @@ class GotoStmt extends JumpStmt, @stmt_goto {
* ``` * ```
* the result is `"someLabel"`. * the result is `"someLabel"`.
*/ */
string getName() { jumpinfo(this,result,_) and result != "" } string getName() { jumpinfo(unresolveElement(this),result,_) and result != "" }
/** Holds if this 'goto' statement refers to a label. */ /** Holds if this 'goto' statement refers to a label. */
predicate hasName() { exists(string s | jumpinfo(this,s,_) and s != "") } predicate hasName() { exists(string s | jumpinfo(unresolveElement(this),s,_) and s != "") }
override string toString() { result = "goto ..." } override string toString() { result = "goto ..." }
@@ -534,7 +534,7 @@ private Stmt getEnclosingBreakable(Stmt s) {
class LabelStmt extends Stmt, @stmt_label { class LabelStmt extends Stmt, @stmt_label {
/** Gets the name of this 'label' statement. */ /** Gets the name of this 'label' statement. */
string getName() { jumpinfo(this,result,_) and result != "" } string getName() { jumpinfo(unresolveElement(this),result,_) and result != "" }
/** Holds if this 'label' statement is named. */ /** Holds if this 'label' statement is named. */
predicate isNamed() { exists(this.getName()) } predicate isNamed() { exists(this.getName()) }
@@ -611,7 +611,7 @@ class DoStmt extends Loop, @stmt_end_test_while {
override Expr getCondition() { result = this.getChild(0) } override Expr getCondition() { result = this.getChild(0) }
override Expr getControllingExpr() { result = this.getCondition() } override Expr getControllingExpr() { result = this.getCondition() }
override Stmt getStmt() { do_body(this, result) } override Stmt getStmt() { do_body(unresolveElement(this), unresolveElement(result)) }
override string toString() { result = "do (...) ..." } override string toString() { result = "do (...) ..." }
@@ -743,7 +743,7 @@ class ForStmt extends Loop, @stmt_for {
* for (; i < 10; i++) { j++ } * for (; i < 10; i++) { j++ }
* ``` * ```
*/ */
Stmt getInitialization() { for_initialization(this, result) } Stmt getInitialization() { for_initialization(unresolveElement(this), unresolveElement(result)) }
/** /**
* Gets the condition expression of this 'for' statement. * Gets the condition expression of this 'for' statement.
@@ -759,7 +759,7 @@ class ForStmt extends Loop, @stmt_for {
* for (i = 0;; i++) { if (i >= 10) break; } * for (i = 0;; i++) { if (i >= 10) break; }
* ``` * ```
*/ */
override Expr getCondition() { for_condition(this, result) } override Expr getCondition() { for_condition(unresolveElement(this), unresolveElement(result)) }
override Expr getControllingExpr() { result = this.getCondition() } override Expr getControllingExpr() { result = this.getCondition() }
/** /**
@@ -776,9 +776,9 @@ class ForStmt extends Loop, @stmt_for {
* for (i = 0; i < 10;) { i++; } * for (i = 0; i < 10;) { i++; }
* ``` * ```
*/ */
Expr getUpdate() { for_update(this, result) } Expr getUpdate() { for_update(unresolveElement(this), unresolveElement(result)) }
override Stmt getStmt() { for_body(this, result) } override Stmt getStmt() { for_body(unresolveElement(this), unresolveElement(result)) }
override string toString() { result = "for(...;...;...) ..." } override string toString() { result = "for(...;...;...) ..." }
@@ -1026,7 +1026,7 @@ class SwitchCase extends Stmt, @stmt_switch_case {
* has result 2. * has result 2.
*/ */
int getChildNum() { int getChildNum() {
switch_case(_, result, this) switch_case(_, result, unresolveElement(this))
} }
/** /**
@@ -1360,7 +1360,7 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* } * }
* ``` * ```
*/ */
Stmt getStmt() { switch_body(this, result) } Stmt getStmt() { switch_body(unresolveElement(this), unresolveElement(result)) }
/** /**
* Gets a 'switch case' statement of this 'switch' statement. * Gets a 'switch case' statement of this 'switch' statement.
@@ -1377,7 +1377,7 @@ class SwitchStmt extends ConditionalStmt, @stmt_switch {
* ``` * ```
* the results are `case 1:`, `case 2:` and `default:`. * the results are `case 1:`, `case 2:` and `default:`.
*/ */
SwitchCase getASwitchCase() { switch_case(this, _, result) } SwitchCase getASwitchCase() { switch_case(unresolveElement(this), _, unresolveElement(result)) }
/** /**
* Gets the 'default case' statement of this 'switch' statement, * Gets the 'default case' statement of this 'switch' statement,
@@ -1662,7 +1662,7 @@ class FunctionTryStmt extends TryStmt {
* A 'catch block', from either C++'s `catch` or Objective C's `@catch`. * A 'catch block', from either C++'s `catch` or Objective C's `@catch`.
*/ */
class CatchBlock extends Block { class CatchBlock extends Block {
CatchBlock() { ishandler(this) } CatchBlock() { ishandler(unresolveElement(this)) }
/** /**
* Gets the parameter introduced by this 'catch block', if any. * Gets the parameter introduced by this 'catch block', if any.
@@ -1752,7 +1752,7 @@ class DeclStmt extends Stmt, @stmt_decl {
* the result of `getDeclarationEntry(0)` is `i`. * the result of `getDeclarationEntry(0)` is `i`.
*/ */
DeclarationEntry getDeclarationEntry(int i) { DeclarationEntry getDeclarationEntry(int i) {
stmt_decl_entry_bind(this, i, result) stmt_decl_entry_bind(unresolveElement(this), i, unresolveElement(result))
} }
/** /**
@@ -1788,7 +1788,7 @@ class DeclStmt extends Stmt, @stmt_decl {
* ``` * ```
* the result of `getDeclaration(0)` is `i`. * the result of `getDeclaration(0)` is `i`.
*/ */
Declaration getDeclaration(int i) { stmt_decl_bind(this, i, result) } Declaration getDeclaration(int i) { stmt_decl_bind(unresolveElement(this), i, unresolveElement(result)) }
/** /**
* Gets a declaration declared by this 'declaration' statement. * Gets a declaration declared by this 'declaration' statement.
@@ -1891,11 +1891,11 @@ class VlaDeclStmt extends Stmt, @stmt_vla_decl {
* Gets the type that this VLA declaration statement relates to, * Gets the type that this VLA declaration statement relates to,
* if any. * if any.
*/ */
Type getType() { type_vla(unresolve(result), this) } Type getType() { type_vla(unresolveElement(result), unresolveElement(this)) }
/** /**
* Gets the variable that this VLA declaration statement relates to, * Gets the variable that this VLA declaration statement relates to,
* if any. * if any.
*/ */
Variable getVariable() { variable_vla(result, this) } Variable getVariable() { variable_vla(unresolveElement(result), unresolveElement(this)) }
} }

View File

@@ -61,12 +61,12 @@ private ControlFlowNode nodeWithPossibleSideEffect() {
or or
// If the lhs of an assignment is not analyzable by SSA, then // If the lhs of an assignment is not analyzable by SSA, then
// we need to treat the assignment as having a possible side-effect. // we need to treat the assignment as having a possible side-effect.
(result instanceof Assignment and not result instanceof SsaDefinition) (result instanceof Assignment and not unresolveElement(result) instanceof SsaDefinition)
or or
(result instanceof CrementOperation and not result instanceof SsaDefinition) (result instanceof CrementOperation and not unresolveElement(result) instanceof SsaDefinition)
or or
exists (LocalVariable v exists (LocalVariable v
| result = v.getInitializer().getExpr() and not result instanceof SsaDefinition) | result = v.getInitializer().getExpr() and not unresolveElement(result) instanceof SsaDefinition)
or or
result instanceof AsmStmt result instanceof AsmStmt
} }

View File

@@ -30,5 +30,5 @@ predicate isSuccessor(boolean isEdge, BasicBlock x, BasicBlock y, string label)
from boolean isEdge, BasicBlock x, BasicBlock y, string label from boolean isEdge, BasicBlock x, BasicBlock y, string label
where isNode(isEdge, x, y, label) or isSuccessor(isEdge, x, y, label) where isNode(isEdge, x, y, label) or isSuccessor(isEdge, x, y, label)
select scope(x), isEdge, x, y, label select scope(mkElement(x)), isEdge, x, y, label

View File

@@ -13,9 +13,9 @@ import semmle.code.cpp.controlflow.SSA
select select
count(SsaDefinition d, LocalScopeVariable v, Expr u | count(SsaDefinition d, LocalScopeVariable v, Expr u |
d.getAUse(v) = u and d.getAUse(v) = u and
not exists(BasicBlock bd, BasicBlock bu | bd.contains((ControlFlowNode)d) and bu.contains(u) | not exists(BasicBlock bd, BasicBlock bu | bd.contains(mkElement(d).(ControlFlowNode)) and bu.contains(u) |
bbStrictlyDominates(bd, bu) bbStrictlyDominates(bd, bu)
or or
exists(int i, int j | bd = bu and bd.getNode(i) = d and bu.getNode(j) = u and i <= j) exists(int i, int j | bd = bu and bd.getNode(i) = mkElement(d) and bu.getNode(j) = u and i <= j)
) )
) )

View File

@@ -3,7 +3,7 @@ import semmle.code.cpp.exprs.ObjectiveC
string arguments(Function f, int i) { string arguments(Function f, int i) {
(result = "," and i = -1) or (result = "," and i = -1) or
(result = "" and i = min(int j | function_template_argument(f, j, _)) - 1) or (result = "" and i = min(int j | function_template_argument(unresolveElement(f), j, _)) - 1) or
(result = arguments(f, i - 1) + "," + f.getTemplateArgument(i).toString()) (result = arguments(f, i - 1) + "," + f.getTemplateArgument(i).toString())
} }

View File

@@ -3,12 +3,12 @@ import semmle.code.cpp.dataflow.DataFlow
class EdgeToExcept extends AdditionalControlFlowEdge { class EdgeToExcept extends AdditionalControlFlowEdge {
EdgeToExcept() { EdgeToExcept() {
this instanceof Call and mkElement(this) instanceof Call and
exists(getNearestTryExceptParent(this)) exists(getNearestTryExceptParent(mkElement(this)))
} }
override ControlFlowNode getAnEdgeTarget() { override ControlFlowNode getAnEdgeTarget() {
result = getNearestTryExceptParent(this).getExcept() result = getNearestTryExceptParent(mkElement(this)).getExcept()
} }
} }
@@ -31,4 +31,4 @@ private Element getANearParent(Expr e) {
from DataFlow::Node nodeFrom, DataFlow::Node nodeTo from DataFlow::Node nodeFrom, DataFlow::Node nodeTo
where DataFlow::localFlowStep(nodeFrom, nodeTo) where DataFlow::localFlowStep(nodeFrom, nodeTo)
select nodeFrom, nodeTo select nodeFrom, nodeTo

View File

@@ -1,5 +1,5 @@
import cpp import cpp
from Expr e, Variable v from Expr e, Variable v
where varbind(e, v) where varbind(unresolveElement(e), unresolveElement(v))
select e, v select e, v

View File

@@ -1,6 +1,6 @@
import cpp import cpp
from Element e, MacroAccess ma from Element e, MacroAccess ma
where affectedbymacroexpansion(e, ma) where affectedbymacroexpansion(unresolveElement(e), unresolveElement(ma))
select e.getLocation(), e, ma.getLocation(), ma select e.getLocation(), e, ma.getLocation(), ma

View File

@@ -1,6 +1,6 @@
import cpp import cpp
from Block b, MacroAccess m from Block b, MacroAccess m
where affectedbymacroexpansion(b, m) where affectedbymacroexpansion(unresolveElement(b), unresolveElement(m))
select b, m select b, m

View File

@@ -1,6 +1,6 @@
import cpp import cpp
from Block b, MacroAccess m from Block b, MacroAccess m
where inmacroexpansion(b, m) where inmacroexpansion(unresolveElement(b), unresolveElement(m))
select b, m select b, m

View File

@@ -11,6 +11,6 @@ string functionName(Function f) {
} }
from string resource, int ntotal, int ncode, int ncomment from string resource, int ntotal, int ncode, int ncomment
where exists(File f | f.getShortName() = resource and numlines(f, ntotal, ncode, ncomment)) where exists(File f | f.getShortName() = resource and numlines(unresolveElement(f), ntotal, ncode, ncomment))
or exists(Function f | functionName(f) = resource and numlines(f, ntotal, ncode, ncomment)) or exists(Function f | functionName(f) = resource and numlines(unresolveElement(f), ntotal, ncode, ncomment))
select resource, ntotal, ncode, ncomment select resource, ntotal, ncode, ncomment

View File

@@ -23,7 +23,7 @@ predicate isSetFlowEnd(boolean isEdge, int x, int y, string label) {
(setflow(x, _) or setflow(_, x)) (setflow(x, _) or setflow(_, x))
and isEdge = false and isEdge = false
and x = y and x = y
and label = "set: {" + concat(Element e | pointstosets(x, e) | e.toString(), ", ") + "}" and label = "set: {" + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ") + "}"
} }
predicate isSetFlow(boolean isEdge, int x, int y, string label) { predicate isSetFlow(boolean isEdge, int x, int y, string label) {
@@ -36,12 +36,12 @@ predicate isPointsToSetSrc(boolean isEdge, int x, int y, string label) {
pointstosets(x, _) pointstosets(x, _)
and isEdge = false and isEdge = false
and x = y and x = y
and label = "set: {" + concat(Element e | pointstosets(x, e) | e.toString(), ", ") + "}" and label = "set: {" + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ") + "}"
} }
predicate isPointsToSetDest(boolean isEdge, Element x, Element y, string label) { predicate isPointsToSetDest(boolean isEdge, Element x, Element y, string label) {
exists(string loc, string name | exists(string loc, string name |
pointstosets(_, x) pointstosets(_, unresolveElement(x))
and isEdge = false and isEdge = false
and x = y and x = y
and (if exists(x.getLocation().toString()) and (if exists(x.getLocation().toString())
@@ -55,9 +55,9 @@ predicate isPointsToSetDest(boolean isEdge, Element x, Element y, string label)
predicate isPointsToSets(boolean isEdge, int x, Element y, string label) { predicate isPointsToSets(boolean isEdge, int x, Element y, string label) {
isEdge = true isEdge = true
and pointstosets(x, y) and pointstosets(x, unresolveElement(y))
and label = "pt: {" and label = "pt: {"
+ concat(Element e | pointstosets(x, e) | e.toString(), ", ") + concat(Element e | pointstosets(x, unresolveElement(e)) | e.toString(), ", ")
+ "} -> " + y.toString() + "} -> " + y.toString()
} }

View File

@@ -13,9 +13,9 @@ import semmle.code.cpp.rangeanalysis.RangeSSA
select select
count(RangeSsaDefinition d, LocalScopeVariable v, Expr u | count(RangeSsaDefinition d, LocalScopeVariable v, Expr u |
d.getAUse(v) = u and d.getAUse(v) = u and
not exists(BasicBlock bd, BasicBlock bu | bd.contains((ControlFlowNode)d) and bu.contains(u) | not exists(BasicBlock bd, BasicBlock bu | bd.contains(mkElement(d).(ControlFlowNode)) and bu.contains(u) |
bbStrictlyDominates(bd, bu) bbStrictlyDominates(bd, bu)
or or
exists(int i, int j | bd = bu and bd.getNode(i) = d and bu.getNode(j) = u and i <= j) exists(int i, int j | bd = bu and bd.getNode(i) = mkElement(d) and bu.getNode(j) = u and i <= j)
) )
) )

View File

@@ -3,7 +3,7 @@ import sbb_test
class CutCall extends SubBasicBlockCutNode { class CutCall extends SubBasicBlockCutNode {
CutCall() { CutCall() {
this.(FunctionCall).getTarget().getName() = "cut" mkElement(this).(FunctionCall).getTarget().getName() = "cut"
} }
} }

View File

@@ -2,7 +2,7 @@ import sbb_test
class CutCall extends SubBasicBlockCutNode { class CutCall extends SubBasicBlockCutNode {
CutCall() { CutCall() {
this.(FunctionCall).getTarget().getName() = "cut" mkElement(this).(FunctionCall).getTarget().getName() = "cut"
} }
} }

View File

@@ -21,8 +21,8 @@ class ParameterMonkeyPatch extends Parameter {
from Element e, Element ti from Element e, Element ti
where e.getLocation().getStartLine() != 0 // unhelpful where e.getLocation().getStartLine() != 0 // unhelpful
and not (function_instantiation(e, _) and e = ti) // trivial and not (function_instantiation(unresolveElement(e), _) and e = ti) // trivial
and not (class_instantiation(e, _) and e = ti) // trivial and not (class_instantiation(unresolveElement(e), _) and e = ti) // trivial
and not (variable_instantiation(e, _) and e = ti) // trivial and not (variable_instantiation(unresolveElement(e), _) and e = ti) // trivial
and e.isFromTemplateInstantiation(ti) and e.isFromTemplateInstantiation(ti)
select e, ti select e, ti

View File

@@ -1,8 +1,8 @@
import cpp import cpp
string integralTypeKind(IntegralType t) { string integralTypeKind(IntegralType t) {
if exists(int kind | builtintypes(t, _, kind, _, _, _)) if exists(int kind | builtintypes(unresolveElement(t), _, kind, _, _, _))
then exists(int kind | builtintypes(t, _, kind, _, _, _) | result = (kind.toString() + " ").prefix(2)) then exists(int kind | builtintypes(unresolveElement(t), _, kind, _, _, _) | result = (kind.toString() + " ").prefix(2))
else result = "--" else result = "--"
} }