C++: Support inline namespaces in hasQualifiedName

This commit is contained in:
Jonas Jensen 2019-05-29 15:18:37 +02:00
Родитель 4bb65fddf7
Коммит df4c57648c
4 изменённых файлов: 28 добавлений и 5 удалений

Просмотреть файл

@ -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.

Просмотреть файл

@ -26,6 +26,22 @@ class Namespace extends @namespace {
else result = this.getName()
}
string getQualifierForMembers() {
if namespacembrs(_, this)
then
exists(Namespace ns |
namespacembrs(ns, this)
|
result = ns.getQualifierForMembers() + "::" + 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.getQualifierForMembers()
)
else result = this.getName()
}
Declaration getADeclaration() {
if this.getName() = ""
then result.isTopLevel() and not namespacembrs(_, result)
@ -331,7 +347,7 @@ cached
private predicate declarationHasQualifiedName(
string baseName, string typeQualifier, string namespaceQualifier, Declaration d
) {
namespaceQualifier = d.getNamespace().getQualifiedName() and
namespaceQualifier = d.getNamespace().getQualifierForMembers() and
(
if hasTypeQualifier(d)
then typeQualifier = d.getTypeQualifierWithoutArgs()

Просмотреть файл

@ -62,12 +62,12 @@ namespace templates {
namespace std {
inline namespace cpp17 {
void functionInTwoNamespaces(); // BUG: should also show up in `std`
class classInTwoNameSpaces { // BUG: should also show up in `std`
void functionInTwoNamespaces();
class classInTwoNameSpaces {
};
inline namespace implementation {
namespace ns {
void functionInFourNamespaces(); // BUG: should also show up the outer namespaces
void functionInFourNamespaces();
}
}
}

Просмотреть файл

@ -52,10 +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 |