mirror of
https://github.com/github/codeql.git
synced 2025-12-18 18:10:39 +01:00
C++: Use mkElement/unresolveElement consistently
This commit is contained in:
@@ -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. */
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)))
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
cpp/ql/src/external/CodeDuplication.qll
vendored
2
cpp/ql/src/external/CodeDuplication.qll
vendored
@@ -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) {
|
||||||
|
|||||||
6
cpp/ql/src/external/VCS.qll
vendored
6
cpp/ql/src/external/VCS.qll
vendored
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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."
|
||||||
|
|||||||
@@ -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))
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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() {
|
||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|
||||||
|
|||||||
@@ -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) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)")
|
||||||
|
|||||||
@@ -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,_,_) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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`.
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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`. */
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|
||||||
|
|||||||
@@ -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&`, and `long` for the SpecifiedType `volatile long`.
|
* `const int` for the ReferenceType `const int&`, 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&).
|
* A C++11 lvalue reference type (e.g. int&).
|
||||||
*/
|
*/
|
||||||
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&&).
|
* A C++11 rvalue reference type (e.g. int&&).
|
||||||
*/
|
*/
|
||||||
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, _)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|
||||||
|
|||||||
@@ -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() }
|
||||||
|
|
||||||
|
|||||||
@@ -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)) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,_)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 (
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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() + ")")
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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(_, _))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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)" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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. */
|
||||||
|
|||||||
@@ -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). */
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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)) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 = "--"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user