Skip to content

Commit 877118f

Browse files
authored
Merge pull request #19274 from MathiasVP/prepare-cpp-for-mad-generation
C++: Prepare for model generation adoption
2 parents 4ae49cf + deef95d commit 877118f

File tree

4 files changed

+63
-17
lines changed

4 files changed

+63
-17
lines changed

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

+16-8
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
465465
}
466466

467467
/** Gets the fully templated version of `f`. */
468-
private Function getFullyTemplatedFunction(Function f) {
468+
Function getFullyTemplatedFunction(Function f) {
469469
not f.isFromUninstantiatedTemplate(_) and
470470
(
471471
exists(Class c, Class templateClass, int i |
@@ -559,27 +559,35 @@ private string getTypeName(Type t, boolean needsSpace) {
559559

560560
/**
561561
* Gets a type name for the `n`'th parameter of `f` without any template
562-
* arguments. The result may be a string representing a type for which the
563-
* typedefs have been resolved.
562+
* arguments.
563+
*
564+
* If `canonical = false` then the result may be a string representing a type
565+
* for which the typedefs have been resolved. If `canonical = true` then the
566+
* result will be a string representing a type without resolving `typedefs`.
564567
*/
565568
bindingset[f]
566569
pragma[inline_late]
567-
string getParameterTypeWithoutTemplateArguments(Function f, int n) {
570+
string getParameterTypeWithoutTemplateArguments(Function f, int n, boolean canonical) {
568571
exists(string s, string base, string specifiers, Type t |
569572
t = f.getParameter(n).getType() and
570573
// The name of the string can either be the possibly typedefed name
571574
// or an alternative name where typedefs has been resolved.
572575
// `getTypeName(t, _)` is almost equal to `t.resolveTypedefs().getName()`,
573576
// except that `t.resolveTypedefs()` doesn't have a result when the
574577
// resulting type doesn't appear in the database.
575-
s = [t.getName(), getTypeName(t, _)] and
578+
(
579+
s = t.getName() and canonical = true
580+
or
581+
s = getTypeName(t, _) and canonical = false
582+
) and
576583
parseAngles(s, base, _, specifiers) and
577584
result = base + specifiers
578585
)
579586
or
580587
f.isVarargs() and
581588
n = f.getNumberOfParameters() and
582-
result = "..."
589+
result = "..." and
590+
canonical = true
583591
}
584592

585593
/**
@@ -590,7 +598,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
590598
exists(Function templateFunction |
591599
templateFunction = getFullyTemplatedFunction(f) and
592600
remaining = templateFunction.getNumberOfTemplateArguments() and
593-
result = getParameterTypeWithoutTemplateArguments(templateFunction, n)
601+
result = getParameterTypeWithoutTemplateArguments(templateFunction, n, _)
594602
)
595603
or
596604
exists(string mid, TypeTemplateParameter tp, Function templateFunction |
@@ -627,7 +635,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
627635
}
628636

629637
/** Gets the string representation of the `i`'th parameter of `c`. */
630-
private string getParameterTypeName(Function c, int i) {
638+
string getParameterTypeName(Function c, int i) {
631639
result = getTypeNameWithoutClassTemplates(c, i, 0)
632640
}
633641

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

+42-4
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
371371
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
372372

373373
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
374-
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
374+
op = call.getArgumentOperand(pos.(DirectPosition).getArgumentIndex())
375375
}
376376
}
377377

@@ -410,8 +410,16 @@ class ParameterPosition = Position;
410410
class ArgumentPosition = Position;
411411

412412
abstract class Position extends TPosition {
413+
/** Gets a textual representation of this position. */
413414
abstract string toString();
414415

416+
/**
417+
* Gets the argument index of this position. The qualifier of a call has
418+
* argument index `-1`.
419+
*/
420+
abstract int getArgumentIndex();
421+
422+
/** Gets the indirection index of this position. */
415423
abstract int getIndirectionIndex();
416424
}
417425

@@ -428,7 +436,7 @@ class DirectPosition extends Position, TDirectPosition {
428436
result = index.toString()
429437
}
430438

431-
int getIndex() { result = index }
439+
override int getArgumentIndex() { result = index }
432440

433441
final override int getIndirectionIndex() { result = 0 }
434442
}
@@ -445,16 +453,29 @@ class IndirectionPosition extends Position, TIndirectionPosition {
445453
else result = repeatStars(indirectionIndex) + argumentIndex.toString()
446454
}
447455

448-
int getArgumentIndex() { result = argumentIndex }
456+
override int getArgumentIndex() { result = argumentIndex }
449457

450458
final override int getIndirectionIndex() { result = indirectionIndex }
451459
}
452460

453461
newtype TPosition =
454-
TDirectPosition(int argumentIndex) { exists(any(CallInstruction c).getArgument(argumentIndex)) } or
462+
TDirectPosition(int argumentIndex) {
463+
exists(any(CallInstruction c).getArgument(argumentIndex))
464+
or
465+
// Handle the rare case where there is a function definition but no call to
466+
// the function.
467+
exists(any(Cpp::Function f).getParameter(argumentIndex))
468+
} or
455469
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
456470
Ssa::hasIndirectOperand(any(CallInstruction call).getArgumentOperand(argumentIndex),
457471
indirectionIndex)
472+
or
473+
// Handle the rare case where there is a function definition but no call to
474+
// the function.
475+
exists(Cpp::Function f, Cpp::Parameter p |
476+
p = f.getParameter(argumentIndex) and
477+
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
478+
)
458479
}
459480

460481
private newtype TReturnKind =
@@ -501,6 +522,15 @@ class ReturnKind extends TReturnKind {
501522

502523
/** Gets a textual representation of this return kind. */
503524
abstract string toString();
525+
526+
/** Holds if this `ReturnKind` is generated from a `return` statement. */
527+
abstract predicate isNormalReturn();
528+
529+
/**
530+
* Holds if this `ReturnKind` is generated from a write to the parameter with
531+
* index `argumentIndex`
532+
*/
533+
abstract predicate isIndirectReturn(int argumentIndex);
504534
}
505535

506536
/**
@@ -514,6 +544,10 @@ class NormalReturnKind extends ReturnKind, TNormalReturnKind {
514544
override int getIndirectionIndex() { result = indirectionIndex }
515545

516546
override string toString() { result = "indirect return" }
547+
548+
override predicate isNormalReturn() { any() }
549+
550+
override predicate isIndirectReturn(int argumentIndex) { none() }
517551
}
518552

519553
/**
@@ -528,6 +562,10 @@ private class IndirectReturnKind extends ReturnKind, TIndirectReturnKind {
528562
override int getIndirectionIndex() { result = indirectionIndex }
529563

530564
override string toString() { result = "indirect outparam[" + argumentIndex.toString() + "]" }
565+
566+
override predicate isNormalReturn() { none() }
567+
568+
override predicate isIndirectReturn(int argumentIndex_) { argumentIndex_ = argumentIndex }
531569
}
532570

533571
/** A data flow node that occurs as the result of a `ReturnStmt`. */

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

+3-3
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ private class ExplicitParameterInstructionNode extends AbstractExplicitParameter
14451445
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
14461446

14471447
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
1448-
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
1448+
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = instr.getParameter()
14491449
}
14501450

14511451
override string toStringImpl() { result = instr.getParameter().toString() }
@@ -1460,7 +1460,7 @@ class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
14601460
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
14611461

14621462
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
1463-
pos.(DirectPosition).getIndex() = -1 and
1463+
pos.(DirectPosition).getArgumentIndex() = -1 and
14641464
instr.getEnclosingFunction() = f
14651465
}
14661466

@@ -1494,7 +1494,7 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
14941494

14951495
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
14961496
this.getFunction() = f and
1497-
f.getParameter(pos.(DirectPosition).getIndex()) = p
1497+
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = p
14981498
}
14991499

15001500
override Parameter getParameter() { result = p }

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll

+2-2
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,11 @@ private module SpeculativeTaintFlow {
229229
not exists(DataFlowDispatch::viableCallable(call)) and
230230
src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos)
231231
|
232-
not argpos.(DirectPosition).getIndex() = -1 and
232+
not argpos.(DirectPosition).getArgumentIndex() = -1 and
233233
sink.(PostUpdateNode)
234234
.getPreUpdateNode()
235235
.(DataFlowPrivate::ArgumentNode)
236-
.argumentOf(call, any(DirectPosition qualpos | qualpos.getIndex() = -1))
236+
.argumentOf(call, any(DirectPosition qualpos | qualpos.getArgumentIndex() = -1))
237237
or
238238
sink.(DataFlowPrivate::OutNode).getCall() = call
239239
)

0 commit comments

Comments
 (0)