Skip to content

Commit 732e55d

Browse files
committed
C++: Ignore template non-type parameters in MaD signature matching.
1 parent c9e9322 commit 732e55d

File tree

1 file changed

+42
-9
lines changed

1 file changed

+42
-9
lines changed

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,17 @@
1515
* reading.
1616
* 1. The `namespace` column selects a namespace.
1717
* 2. The `type` column selects a type within that namespace. This column can
18-
* introduce template names that can be mentioned in the `signature` column.
18+
* introduce template type names that can be mentioned in the `signature` column.
1919
* For example, `vector<T,Allocator>` introduces the template names `T` and
20-
* `Allocator`.
20+
* `Allocator`. Non-type template parameters cannot be specified.
2121
* 3. The `subtypes` is a boolean that indicates whether to jump to an
2222
* arbitrary subtype of that type. Set this to `false` if leaving the `type`
2323
* blank (for example, a free function).
2424
* 4. The `name` column optionally selects a specific named member of the type.
25-
* Like the `type` column, this column can introduce template names that can
26-
* be mentioned in the `signature` column. For example, `insert<InputIt>`
27-
* introduces the template name `InputIt`.
25+
* Like the `type` column, this column can introduce template type names
26+
* that can be mentioned in the `signature` column. For example,
27+
* `insert<InputIt>` introduces the template name `InputIt`. Non-type
28+
* template parameters cannot be specified.
2829
* 5. The `signature` column optionally restricts the named member. If
2930
* `signature` is blank then no such filtering is done. The format of the
3031
* signature is a comma-separated list of types enclosed in parentheses. The
@@ -633,25 +634,56 @@ string getParameterTypeWithoutTemplateArguments(Function f, int n, boolean canon
633634
canonical = true
634635
}
635636

637+
/** Gets the `i`'th supported template parameter for `templateFunction`. */
638+
private Locatable getSupportedFunctionTemplateArgument(Function templateFunction, int i) {
639+
result =
640+
rank[i + 1](int j, TypeTemplateParameter ttp |
641+
ttp = templateFunction.getTemplateArgument(j)
642+
|
643+
ttp order by j
644+
)
645+
}
646+
647+
/** Gets the number of supported template parameters for `templateFunction`. */
648+
private int getNumberOfSupportedFunctionTemplateArguments(Function templateFunction) {
649+
result = count(int i | exists(getSupportedFunctionTemplateArgument(templateFunction, i)) | i)
650+
}
651+
636652
/**
637653
* Normalize the `n`'th parameter of `f` by replacing template names
638654
* with `func:N` (where `N` is the index of the template).
639655
*/
640656
private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remaining) {
641657
exists(Function templateFunction |
642658
templateFunction = getFullyTemplatedFunction(f) and
643-
remaining = templateFunction.getNumberOfTemplateArguments() and
659+
remaining = getNumberOfSupportedFunctionTemplateArguments(templateFunction) and
644660
result = getParameterTypeWithoutTemplateArguments(templateFunction, n, _)
645661
)
646662
or
647663
exists(string mid, TypeTemplateParameter tp, Function templateFunction |
648664
mid = getTypeNameWithoutFunctionTemplates(f, n, remaining + 1) and
649665
templateFunction = getFullyTemplatedFunction(f) and
650-
tp = templateFunction.getTemplateArgument(remaining) and
666+
tp = getSupportedFunctionTemplateArgument(templateFunction, remaining)
667+
|
651668
result = mid.replaceAll(tp.getName(), "func:" + remaining.toString())
652669
)
653670
}
654671

672+
/** Gets the `i`'th support template parameter for `templateClass`. */
673+
private Locatable getSupportedClassTemplateArgument(Class templateClass, int i) {
674+
result =
675+
rank[i + 1](int j, TypeTemplateParameter ttp |
676+
ttp = templateClass.getTemplateArgument(j)
677+
|
678+
ttp order by j
679+
)
680+
}
681+
682+
/** Gets the number of supported template parameters for `templateClass`. */
683+
private int getNumberOfSupportedClassTemplateArguments(Class templateClass) {
684+
result = count(int i | exists(getSupportedClassTemplateArgument(templateClass, i)) | i)
685+
}
686+
655687
/**
656688
* Normalize the `n`'th parameter of `f` by replacing template names
657689
* with `class:N` (where `N` is the index of the template).
@@ -661,7 +693,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
661693
// If there is a declaring type then we start by expanding the function templates
662694
exists(Class template |
663695
isClassConstructedFrom(f.getDeclaringType(), template) and
664-
remaining = template.getNumberOfTemplateArguments() and
696+
remaining = getNumberOfSupportedClassTemplateArguments(template) and
665697
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
666698
)
667699
or
@@ -673,7 +705,8 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
673705
exists(string mid, TypeTemplateParameter tp, Class template |
674706
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
675707
isClassConstructedFrom(f.getDeclaringType(), template) and
676-
tp = template.getTemplateArgument(remaining) and
708+
tp = getSupportedClassTemplateArgument(template, remaining)
709+
|
677710
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
678711
)
679712
}

0 commit comments

Comments
 (0)