Files
codeql/cpp/ql/lib/semmle/code/cpp/Enclosing.qll
Andrew Eisenberg 2c5dd2dfa3 Packaging: Refactor the cpp libraries
This PR separates the core cpp packs into `codeql/cpp-queries` and
`codeql/cpp-all`.

There are very few lines of code changed. Almost all changes are moving
files around.
2021-08-17 11:22:36 -07:00

64 lines
1.8 KiB
Plaintext

/**
* Provides predicates for finding the smallest element that encloses an expression or statement.
*/
import cpp
/**
* Gets the enclosing element of statement `s`.
*/
cached
Element stmtEnclosingElement(Stmt s) {
result.(Function).getEntryPoint() = s or
result = stmtEnclosingElement(s.getParent()) or
result = exprEnclosingElement(s.getParent())
}
/**
* Gets the enclosing element of expression `e`.
*/
// The `pragma[nomagic]` is a workaround to prevent this cached stage (and all
// subsequent stages) from being evaluated twice. See QL-888. It has the effect
// of making the `Conversion` class predicate get the same optimization in all
// queries.
pragma[nomagic]
cached
Element exprEnclosingElement(Expr e) {
result = exprEnclosingElement(e.getParent())
or
result = stmtEnclosingElement(e.getParent())
or
result.(Function) = e.getParent()
or
result = exprEnclosingElement(e.(Conversion).getExpr())
or
exists(Initializer i |
i.getExpr() = e and
if exists(i.getEnclosingStmt())
then result = stmtEnclosingElement(i.getEnclosingStmt())
else
if i.getDeclaration() instanceof Parameter
then result = i.getDeclaration().(Parameter).getFunction()
else result = i.getDeclaration()
)
or
exists(Expr anc |
expr_ancestor(unresolveElement(e), unresolveElement(anc)) and result = exprEnclosingElement(anc)
)
or
exists(Stmt anc |
expr_ancestor(unresolveElement(e), unresolveElement(anc)) and result = stmtEnclosingElement(anc)
)
or
exists(DeclarationEntry de |
expr_ancestor(unresolveElement(e), unresolveElement(de)) and
if exists(DeclStmt ds | de = ds.getADeclarationEntry())
then
exists(DeclStmt ds |
de = ds.getADeclarationEntry() and
result = stmtEnclosingElement(ds)
)
else result = de.getDeclaration()
)
}