Skip to content

Commit 3d3feb6

Browse files
committed
C++: Also resolve typedefs when parsing MaD model parameter names.
1 parent 5ccc12c commit 3d3feb6

File tree

1 file changed

+76
-4
lines changed

1 file changed

+76
-4
lines changed

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

Lines changed: 76 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,87 @@ private Function getFullyTemplatedFunction(Function f) {
479479
)
480480
}
481481

482+
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
483+
bindingset[s, t]
484+
private string withConst(string s, Type t) {
485+
if t.isConst() then result = "const " + s else result = s
486+
}
487+
488+
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
489+
bindingset[s, t]
490+
private string withVolatile(string s, Type t) {
491+
if t.isVolatile() then result = "volatile " + s else result = s
492+
}
493+
494+
/**
495+
* Returns `s` prefixed with appropriate speciiers from `t`, or `s` if `t` has
496+
* no relevant specifiers.
497+
*/
498+
bindingset[s, t]
499+
private string withSpecifiers(string s, Type t) {
500+
// An `int` that is both const and volatile will be printed as
501+
// `const volatile int` to match the behavior of `Type.getName` which
502+
// is generated by the extractor.
503+
result = withConst(withVolatile(s, t), t)
504+
}
505+
506+
/**
507+
* Gets the string version of `t`. The boolean `needsSpace` is `true`
508+
* if a space should be appended before concatenating any additional symbols
509+
* (such as `*` or `&`) when recursively constructing the type name.
510+
*/
511+
private string getTypeName(Type t, boolean needsSpace) {
512+
// We don't care about template instantiations since we always base models
513+
// on the uninstantiated templates
514+
not t.isFromTemplateInstantiation(_) and
515+
(
516+
exists(DerivedType dt, string s, boolean needsSpace0 |
517+
dt = t and s = withSpecifiers(getTypeName(dt.getBaseType(), needsSpace0), dt)
518+
|
519+
dt instanceof ReferenceType and
520+
not dt instanceof RValueReferenceType and
521+
needsSpace = false and
522+
(if needsSpace0 = true then result = s + " &" else result = s + "&")
523+
or
524+
dt instanceof RValueReferenceType and
525+
needsSpace = false and
526+
(if needsSpace0 = true then result = s + " &&" else result = s + "&&")
527+
or
528+
dt instanceof PointerType and
529+
needsSpace = false and
530+
(if needsSpace0 = true then result = s + " *" else result = s + "*")
531+
or
532+
not dt instanceof ReferenceType and
533+
not dt instanceof PointerType and
534+
result = s and
535+
needsSpace = needsSpace0
536+
)
537+
or
538+
not t instanceof DerivedType and
539+
not t instanceof TypedefType and
540+
result = t.getName() and
541+
(if result.matches(["%*", "%&", "%]"]) then needsSpace = false else needsSpace = true)
542+
)
543+
or
544+
result = getTypeName(t.(TypedefType).getBaseType(), needsSpace)
545+
}
546+
482547
/**
483-
* Gets the type name of the `n`'th parameter of `f` without any template
484-
* arguments.
548+
* Gets a type name for the `n`'th parameter of `f` without any template
549+
* arguments. The result may be a string representing a type for which the
550+
* typedefs have been resolved.
485551
*/
486552
bindingset[f]
487553
pragma[inline_late]
488554
string getParameterTypeWithoutTemplateArguments(Function f, int n) {
489-
exists(string s, string base, string specifiers |
490-
s = f.getParameter(n).getType().getName() and
555+
exists(string s, string base, string specifiers, Type t |
556+
t = f.getParameter(n).getType() and
557+
// The name of the string can either be the possibly typedefed name
558+
// or an alternartive name where typedefs has been resolved.
559+
// `getTypeName(t, _)` is almost equal to `t.resolveTypedefs().getName()`,
560+
// except that `t.resolveTypedefs()` doesn't have a result when the
561+
// resulting type doesn't appear in the database.
562+
s = [t.getName(), getTypeName(t, _)] and
491563
parseAngles(s, base, _, specifiers) and
492564
result = base + specifiers
493565
)

0 commit comments

Comments
 (0)