From 39a5f228d13ad04e05b502d871bffa7f4c8b40c3 Mon Sep 17 00:00:00 2001 From: Pavel Avgustinov Date: Thu, 27 Sep 2018 10:25:28 +0100 Subject: [PATCH 1/2] Definitions: Only emit links for canonical type mentions --- cpp/ql/src/definitions.qll | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/src/definitions.qll index b067c22040ce..6f8ca88dbca2 100644 --- a/cpp/ql/src/definitions.qll +++ b/cpp/ql/src/definitions.qll @@ -126,6 +126,28 @@ private cached predicate constructorCallTypeMention(ConstructorCall cc, TypeMent ) } +/** + * We sometimes produce many type mentions at the same location that + * refer to the same type. For the purposes of providing a definition + * link, we only want one of them. + */ +private module TypeMentions { + private + predicate identity(TypeMention a, TypeMention b) { a = b } + + private + int id(TypeMention a) = equivalenceRelation(identity/2)(a, result) + + private + TypeMention minMentionIdAt(Location l, Type t) { + result = min(TypeMention m | l = m.getLocation() and t = m.getMentionedType() | m order by id(m)) + } + + predicate isCanonical(TypeMention m) { + m = minMentionIdAt(_, _) + } +} + /** * Gets an element, of kind `kind`, that element `e` uses, if any. * @@ -156,7 +178,9 @@ Top definitionOf(Top e, string kind) { ) or ( // type mention -> type kind = "T" and + TypeMentions::isCanonical(e) and e.(TypeMention).getMentionedType() = result and + not result instanceof ClassTemplateInstantiation and not constructorCallTypeMention(_, e) and // handled elsewhere // Multiple type mentions can be generated when a typedef is used, and // in such cases we want to exclude all but the originating typedef. @@ -177,6 +201,7 @@ Top definitionOf(Top e, string kind) { // - using the location of the type mention, since it's // tighter that the location of the function call. kind = "M" and + TypeMentions::isCanonical(e) and exists(ConstructorCall cc | constructorCallTypeMention(cc, e) and result = cc.getTarget() From 382c7efcd9818793dbaa2a57674a23010eaab9fb Mon Sep 17 00:00:00 2001 From: Pavel Avgustinov Date: Thu, 27 Sep 2018 13:57:28 +0100 Subject: [PATCH 2/2] Reintroduce definition links for template instantiations --- cpp/ql/src/definitions.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/src/definitions.qll index 6f8ca88dbca2..2625e085f90f 100644 --- a/cpp/ql/src/definitions.qll +++ b/cpp/ql/src/definitions.qll @@ -180,7 +180,6 @@ Top definitionOf(Top e, string kind) { kind = "T" and TypeMentions::isCanonical(e) and e.(TypeMention).getMentionedType() = result and - not result instanceof ClassTemplateInstantiation and not constructorCallTypeMention(_, e) and // handled elsewhere // Multiple type mentions can be generated when a typedef is used, and // in such cases we want to exclude all but the originating typedef.