Skip to content
Open
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
80 changes: 76 additions & 4 deletions cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,45 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
not c.isConstructedFrom(_) and c = templateClass
}

/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClassOld(Class c) {
not c.isFromUninstantiatedTemplate(_) and
isClassConstructedFrom(c, result)
}

private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
result = tc.getOriginalTemplate()
or
not exists(tc.getOriginalTemplate()) and
result = tc
}

/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClassNew(Class c) {
not c.isFromUninstantiatedTemplate(_) and
exists(Class mid |
c.isConstructedFrom(mid)
or
not c.isConstructedFrom(_) and c = mid
|
result = getOriginalClassTemplate(mid)
or
not mid instanceof TemplateClass and mid = result
)
}

/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClass(Class c) {
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
// version 2.25.6 and the upgrade script leaves the
// `class_template_generated_from` extensionals empty if the database
// was generated with an older extractor. So we use the old implementation
// if the `class_template_generated_from` extensional is empty.
if class_template_generated_from(_, _)
then result = getFullyTemplatedClassNew(c)
else result = getFullyTemplatedClassOld(c)
}

/**
* Holds if `f` is an instantiation of a function template `templateFunc`, or
* holds with `f = templateFunc` if `f` is not an instantiation of any function
Expand All @@ -292,7 +331,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
}

/** Gets the fully templated version of `f`. */
Function getFullyTemplatedFunction(Function f) {
private Function getFullyTemplatedFunctionOld(Function f) {
not f.isFromUninstantiatedTemplate(_) and
(
exists(Class c, Class templateClass, int i |
Expand All @@ -306,13 +345,46 @@ Function getFullyTemplatedFunction(Function f) {
)
}

private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
result = tf.getOriginalTemplate()
or
not exists(tf.getOriginalTemplate()) and
result = tf
}

/** Gets the fully templated version of `f`. */
private Function getFullyTemplatedFunctionNew(Function f) {
not f.isFromUninstantiatedTemplate(_) and
exists(Function mid |
f.isConstructedFrom(mid)
or
not f.isConstructedFrom(_) and f = mid
|
result = getOriginalFunctionTemplate(mid)
or
not mid instanceof TemplateFunction and mid = result
)
}

/** Gets the fully templated version of `f`. */
Function getFullyTemplatedFunction(Function f) {
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
// version 2.25.6 and the upgrade script leaves the
// `function_template_generated_from` extensionals empty if the database
// was generated with an older extractor. So we use the old implementation
// if the `function_template_generated_from` extensional is empty.
if function_template_generated_from(_, _)
then result = getFullyTemplatedFunctionNew(f)
else result = getFullyTemplatedFunctionOld(f)
}

/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
bindingset[s, t]
private string withConst(string s, Type t) {
if t.isConst() then result = "const " + s else result = s
}

/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */
bindingset[s, t]
private string withVolatile(string s, Type t) {
if t.isVolatile() then result = "volatile " + s else result = s
Expand Down Expand Up @@ -490,7 +562,7 @@ pragma[nomagic]
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
// If there is a declaring type then we start by expanding the function templates
exists(Class template |
isClassConstructedFrom(f.getDeclaringType(), template) and
template = getFullyTemplatedClass(f.getDeclaringType()) and
remaining = getNumberOfSupportedClassTemplateArguments(template) and
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
)
Expand All @@ -502,7 +574,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
or
exists(string mid, TypeTemplateParameter tp, Class template |
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
isClassConstructedFrom(f.getDeclaringType(), template) and
template = getFullyTemplatedClass(f.getDeclaringType()) and
tp = getSupportedClassTemplateArgument(template, remaining)
|
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27383,54 +27383,55 @@ getParameterTypeName
| stl.h:91:24:91:33 | operator++ | 0 | int |
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
| stl.h:95:44:95:44 | back_inserter | 0 | func:0 & |
| stl.h:148:3:148:14 | basic_string | 0 | const class:2 & |
| stl.h:149:33:149:44 | basic_string | 0 | const class:0 * |
| stl.h:149:33:149:44 | basic_string | 1 | const class:2 & |
| stl.h:151:16:151:20 | c_str | 0 | func:0 |
| stl.h:151:16:151:20 | c_str | 1 | func:0 |
| stl.h:151:16:151:20 | c_str | 2 | const class:2 & |
| stl.h:147:12:147:23 | basic_string | 0 | const class:2 & |
| stl.h:148:3:148:14 | basic_string | 0 | const class:0 * |
| stl.h:148:3:148:14 | basic_string | 1 | const class:2 & |
| stl.h:149:33:149:44 | basic_string | 0 | func:0 |
| stl.h:149:33:149:44 | basic_string | 1 | func:0 |
| stl.h:149:33:149:44 | basic_string | 2 | const class:2 & |
| stl.h:165:8:165:16 | push_back | 0 | class:0 |
| stl.h:173:13:173:22 | operator[] | 0 | size_type |
| stl.h:175:13:175:14 | at | 0 | size_type |
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
| stl.h:176:35:176:44 | operator+= | 0 | size_type |
| stl.h:177:17:177:26 | operator+= | 0 | const func:0 & |
| stl.h:178:17:178:22 | append | 0 | const class:0 * |
| stl.h:179:17:179:22 | append | 0 | const basic_string & |
| stl.h:180:17:180:22 | append | 0 | const class:0 * |
| stl.h:181:47:181:52 | append | 0 | size_type |
| stl.h:181:47:181:52 | append | 1 | class:0 |
| stl.h:182:17:182:22 | assign | 0 | func:0 |
| stl.h:182:17:182:22 | assign | 1 | func:0 |
| stl.h:183:17:183:22 | assign | 0 | const basic_string & |
| stl.h:184:47:184:52 | assign | 0 | size_type |
| stl.h:184:47:184:52 | assign | 1 | class:0 |
| stl.h:185:17:185:22 | insert | 0 | func:0 |
| stl.h:185:17:185:22 | insert | 1 | func:0 |
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
| stl.h:176:35:176:44 | operator+= | 0 | const func:0 & |
| stl.h:177:17:177:26 | operator+= | 0 | const class:0 * |
| stl.h:178:17:178:22 | append | 0 | const basic_string & |
| stl.h:179:17:179:22 | append | 0 | const class:0 * |
| stl.h:180:17:180:22 | append | 0 | size_type |
| stl.h:180:17:180:22 | append | 1 | class:0 |
| stl.h:181:47:181:52 | append | 0 | func:0 |
| stl.h:181:47:181:52 | append | 1 | func:0 |
| stl.h:182:17:182:22 | assign | 0 | const basic_string & |
| stl.h:183:17:183:22 | assign | 0 | size_type |
| stl.h:183:17:183:22 | assign | 1 | class:0 |
| stl.h:184:47:184:52 | assign | 0 | func:0 |
| stl.h:184:47:184:52 | assign | 1 | func:0 |
| stl.h:185:17:185:22 | insert | 0 | size_type |
| stl.h:185:17:185:22 | insert | 1 | const basic_string & |
| stl.h:186:17:186:22 | insert | 0 | size_type |
| stl.h:186:17:186:22 | insert | 1 | const basic_string & |
| stl.h:186:17:186:22 | insert | 1 | size_type |
| stl.h:186:17:186:22 | insert | 2 | class:0 |
| stl.h:187:17:187:22 | insert | 0 | size_type |
| stl.h:187:17:187:22 | insert | 1 | size_type |
| stl.h:187:17:187:22 | insert | 2 | class:0 |
| stl.h:188:12:188:17 | insert | 0 | size_type |
| stl.h:188:12:188:17 | insert | 1 | const class:0 * |
| stl.h:187:17:187:22 | insert | 1 | const class:0 * |
| stl.h:188:12:188:17 | insert | 0 | const_iterator |
| stl.h:188:12:188:17 | insert | 1 | size_type |
| stl.h:188:12:188:17 | insert | 2 | class:0 |
| stl.h:189:42:189:47 | insert | 0 | const_iterator |
| stl.h:189:42:189:47 | insert | 1 | size_type |
| stl.h:189:42:189:47 | insert | 2 | class:0 |
| stl.h:190:17:190:23 | replace | 0 | const_iterator |
| stl.h:190:17:190:23 | replace | 1 | func:0 |
| stl.h:190:17:190:23 | replace | 2 | func:0 |
| stl.h:189:42:189:47 | insert | 1 | func:0 |
| stl.h:189:42:189:47 | insert | 2 | func:0 |
| stl.h:190:17:190:23 | replace | 0 | size_type |
| stl.h:190:17:190:23 | replace | 1 | size_type |
| stl.h:190:17:190:23 | replace | 2 | const basic_string & |
| stl.h:191:17:191:23 | replace | 0 | size_type |
| stl.h:191:17:191:23 | replace | 1 | size_type |
| stl.h:191:17:191:23 | replace | 2 | const basic_string & |
| stl.h:192:13:192:16 | copy | 0 | size_type |
| stl.h:191:17:191:23 | replace | 2 | size_type |
| stl.h:191:17:191:23 | replace | 3 | class:0 |
| stl.h:192:13:192:16 | copy | 0 | class:0 * |
| stl.h:192:13:192:16 | copy | 1 | size_type |
| stl.h:192:13:192:16 | copy | 2 | size_type |
| stl.h:192:13:192:16 | copy | 3 | class:0 |
| stl.h:193:8:193:12 | clear | 0 | class:0 * |
| stl.h:193:8:193:12 | clear | 1 | size_type |
| stl.h:193:8:193:12 | clear | 2 | size_type |
| stl.h:195:8:195:11 | swap | 0 | size_type |
| stl.h:195:8:195:11 | swap | 1 | size_type |
| stl.h:194:16:194:21 | substr | 0 | size_type |
| stl.h:194:16:194:21 | substr | 1 | size_type |
| stl.h:195:8:195:11 | swap | 0 | basic_string & |
| stl.h:198:94:198:102 | operator+ | 0 | const basic_string & |
| stl.h:198:94:198:102 | operator+ | 1 | const basic_string & |
| stl.h:199:94:199:102 | operator+ | 0 | const basic_string & |
Expand Down
Loading