Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion change-notes/1.21/analysis-cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

## Changes to QL libraries
- The predicate `Declaration.hasGlobalName` now only holds for declarations that are not nested in a class. For example, it no longer holds for a member function `MyClass::myFunction` or a constructor `MyClass::MyClass`, whereas previously it would classify those two declarations as global names.
- In class `Declaration`, predicates `getQualifiedName/0` and `hasQualifiedName/1` are no longer recommended for finding functions by name. Instead, use `hasGlobalName/1` and the new `hasQualifiedName/2` and `hasQualifiedName/3` predicates. This improves performance and makes it more reliable to identify names involving templates.
- In class `Declaration`, predicates `getQualifiedName/0` and `hasQualifiedName/1` are no longer recommended for finding functions by name. Instead, use `hasGlobalName/1` and the new `hasQualifiedName/2` and `hasQualifiedName/3` predicates. This improves performance and makes it more reliable to identify names involving templates and inline namespaces.
- Additional support for definition by reference has been added to the `semmle.code.cpp.dataflow.TaintTracking` library.
- The taint tracking library now includes taint-specific edges for functions modeled in `semmle.code.cpp.models.interfaces.DataFlow`.
- The taint tracking library adds flow through library functions that are modeled in `semmle.code.cpp.models.interfaces.Taint`. Queries can add subclasses of `TaintFunction` to specify additional flow.
Expand Down
28 changes: 27 additions & 1 deletion cpp/ql/src/semmle/code/cpp/internal/QualifiedName.qll
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ class Namespace extends @namespace {
else result = this.getName()
}

/**
* Gets a namespace qualifier, like `"namespace1::namespace2"`, through which
* the members of this namespace can be named. When `inline namespace` is
* used, this predicate may have multiple results.
*
* This predicate does not take namespace aliases into account. Unlike inline
* namespaces, specialization of templates cannot happen through an alias.
* Aliases are also local to the compilation unit, while inline namespaces
* affect the whole program.
*/
string getAQualifierForMembers() {
if namespacembrs(_, this)
then
exists(Namespace ns |
namespacembrs(ns, this)
|
result = ns.getAQualifierForMembers() + "::" + this.getName()
or
// If this is an inline namespace, its members are also visible in any
// namespace where the members of the parent are visible.
namespace_inline(this) and
result = ns.getAQualifierForMembers()
)
else result = this.getName()
}

Declaration getADeclaration() {
if this.getName() = ""
then result.isTopLevel() and not namespacembrs(_, result)
Expand Down Expand Up @@ -331,7 +357,7 @@ cached
private predicate declarationHasQualifiedName(
string baseName, string typeQualifier, string namespaceQualifier, Declaration d
) {
namespaceQualifier = d.getNamespace().getQualifiedName() and
namespaceQualifier = d.getNamespace().getAQualifierForMembers() and
(
if hasTypeQualifier(d)
then typeQualifier = d.getTypeQualifierWithoutArgs()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,26 @@ namespace templates {
return getMember(tc, typedefC());
}
}

namespace std {
inline namespace cpp17 {
void functionInTwoNamespaces();
class classInTwoNameSpaces {
};
inline namespace implementation {
namespace ns {
void functionInFourNamespaces();
}
}
}
}

// This code demonstrates that `functionInFourNamespaces` is indeed visible in
// four name spaces.
using void_fptr = void(*)();
void_fptr ptrs[] = {
std::ns::functionInFourNamespaces,
std::cpp17::ns::functionInFourNamespaces,
std::implementation::ns::functionInFourNamespaces,
std::cpp17::implementation::ns::functionInFourNamespaces,
};
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,17 @@
| qualifiedNames.cpp:53:12:53:12 | getMember | templates::getMember | templates | | getMember | (not global) |
| qualifiedNames.cpp:53:12:53:20 | getMember | templates::getMember | templates | | getMember | (not global) |
| qualifiedNames.cpp:57:8:57:10 | use | templates::use | templates | | use | (not global) |
| qualifiedNames.cpp:65:10:65:32 | functionInTwoNamespaces | std::cpp17::functionInTwoNamespaces | std | | functionInTwoNamespaces | (not global) |
| qualifiedNames.cpp:65:10:65:32 | functionInTwoNamespaces | std::cpp17::functionInTwoNamespaces | std::cpp17 | | functionInTwoNamespaces | (not global) |
| qualifiedNames.cpp:66:11:66:11 | operator= | std::cpp17::classInTwoNameSpaces::operator= | std | classInTwoNameSpaces | operator= | (not global) |
| qualifiedNames.cpp:66:11:66:11 | operator= | std::cpp17::classInTwoNameSpaces::operator= | std | classInTwoNameSpaces | operator= | (not global) |
| qualifiedNames.cpp:66:11:66:11 | operator= | std::cpp17::classInTwoNameSpaces::operator= | std::cpp17 | classInTwoNameSpaces | operator= | (not global) |
| qualifiedNames.cpp:66:11:66:11 | operator= | std::cpp17::classInTwoNameSpaces::operator= | std::cpp17 | classInTwoNameSpaces | operator= | (not global) |
| qualifiedNames.cpp:66:11:66:30 | classInTwoNameSpaces | std::cpp17::classInTwoNameSpaces | std | | classInTwoNameSpaces | (not global) |
| qualifiedNames.cpp:66:11:66:30 | classInTwoNameSpaces | std::cpp17::classInTwoNameSpaces | std::cpp17 | | classInTwoNameSpaces | (not global) |
| qualifiedNames.cpp:70:14:70:37 | functionInFourNamespaces | std::cpp17::implementation::ns::functionInFourNamespaces | std::cpp17::implementation::ns | | functionInFourNamespaces | (not global) |
| qualifiedNames.cpp:70:14:70:37 | functionInFourNamespaces | std::cpp17::implementation::ns::functionInFourNamespaces | std::cpp17::ns | | functionInFourNamespaces | (not global) |
| qualifiedNames.cpp:70:14:70:37 | functionInFourNamespaces | std::cpp17::implementation::ns::functionInFourNamespaces | std::implementation::ns | | functionInFourNamespaces | (not global) |
| qualifiedNames.cpp:70:14:70:37 | functionInFourNamespaces | std::cpp17::implementation::ns::functionInFourNamespaces | std::ns | | functionInFourNamespaces | (not global) |
| qualifiedNames.cpp:78:7:78:15 | void_fptr | void_fptr | | | void_fptr | void_fptr |
| qualifiedNames.cpp:79:11:79:14 | ptrs | ptrs | | | ptrs | ptrs |