From ffa3e9599f637e083d8b586d519cc915f8fe608d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 15 Jul 2026 19:05:01 +0100 Subject: [PATCH] C++: Add MaD summaries for shared_ptr, unique_ptr, and weak_ptr. Also some TODOs related to follow-up work. This is currently blocked on github/codeql#22145. --- cpp/ql/lib/ext/std.shared_ptr.model.yml | 38 +++++++++++++++++++ cpp/ql/lib/ext/std.unique_ptr.model.yml | 25 ++++++++++++ cpp/ql/lib/ext/std.weak_ptr.model.yml | 19 ++++++++++ .../ir/dataflow/internal/DataFlowDispatch.qll | 8 ++++ .../ir/dataflow/internal/SsaImplCommon.qll | 13 ------- 5 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 cpp/ql/lib/ext/std.shared_ptr.model.yml create mode 100644 cpp/ql/lib/ext/std.unique_ptr.model.yml create mode 100644 cpp/ql/lib/ext/std.weak_ptr.model.yml diff --git a/cpp/ql/lib/ext/std.shared_ptr.model.yml b/cpp/ql/lib/ext/std.shared_ptr.model.yml new file mode 100644 index 000000000000..03cd598b6377 --- /dev/null +++ b/cpp/ql/lib/ext/std.shared_ptr.model.yml @@ -0,0 +1,38 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["std", "shared_ptr", True, "shared_ptr", "(T *)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(Y *)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(Y *,D)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(Y *,D,A)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(const shared_ptr &,T *)", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(shared_ptr &&,T *)", "", "Argument[*@1]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(const shared_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(shared_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(const weak_ptr &)", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "shared_ptr", "(unique_ptr &&)", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(const shared_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(shared_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(shared_ptr &&)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(unique_ptr &&)", "", "Argument[*0].Element[@]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "operator=", "(unique_ptr &&)", "", "Argument[*0].Element[@]", "ReturnValue[*].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "get", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "shared_ptr", True, "operator*", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "shared_ptr", True, "operator->", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "shared_ptr", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "shared_ptr", True, "reset", "", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "shared_ptr", True, "swap", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] + - ["std", "shared_ptr", True, "swap", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "", False, "swap", "(shared_ptr &,shared_ptr &)", "", "Argument[*0].Element[@]", "Argument[*1].Element[@]", "value", "manual"] + - ["std", "", False, "swap", "(shared_ptr &,shared_ptr &)", "", "Argument[*1].Element[@]", "Argument[*0].Element[@]", "value", "manual"] + - ["std", "", False, "static_pointer_cast", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "static_pointer_cast", "(shared_ptr &&)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "dynamic_pointer_cast", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "dynamic_pointer_cast", "(shared_ptr &&)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "const_pointer_cast", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "const_pointer_cast", "(shared_ptr &&)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "reinterpret_pointer_cast", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue", "value", "manual"] + - ["std", "", False, "reinterpret_pointer_cast", "(shared_ptr &&)", "", "Argument[*0]", "ReturnValue", "value", "manual"] diff --git a/cpp/ql/lib/ext/std.unique_ptr.model.yml b/cpp/ql/lib/ext/std.unique_ptr.model.yml new file mode 100644 index 000000000000..75c190cd28a8 --- /dev/null +++ b/cpp/ql/lib/ext/std.unique_ptr.model.yml @@ -0,0 +1,25 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["std", "unique_ptr", True, "unique_ptr", "(T *)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,const D &)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,D &)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,D &&)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,const D &)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,D &)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(T *,D &&)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "unique_ptr", "(unique_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "unique_ptr", True, "operator=", "(unique_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "unique_ptr", True, "operator=", "(unique_ptr &&)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "unique_ptr", True, "get", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "unique_ptr", True, "operator*", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "unique_ptr", True, "operator->", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "unique_ptr", True, "operator[]", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "unique_ptr", True, "release", "", "", "Argument[-1].Element[@]", "ReturnValue[*@]", "value", "manual"] + - ["std", "unique_ptr", True, "reset", "(T *)", "", "Argument[*@0]", "Argument[-1].Element[@]", "value", "manual"] + - ["std", "unique_ptr", True, "swap", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] + - ["std", "unique_ptr", True, "swap", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "", False, "swap", "(unique_ptr &,unique_ptr &)", "", "Argument[*0].Element[@]", "Argument[*1].Element[@]", "value", "manual"] + - ["std", "", False, "swap", "(unique_ptr &,unique_ptr &)", "", "Argument[*1].Element[@]", "Argument[*0].Element[@]", "value", "manual"] diff --git a/cpp/ql/lib/ext/std.weak_ptr.model.yml b/cpp/ql/lib/ext/std.weak_ptr.model.yml new file mode 100644 index 000000000000..68a073ac030c --- /dev/null +++ b/cpp/ql/lib/ext/std.weak_ptr.model.yml @@ -0,0 +1,19 @@ +extensions: + - addsTo: + pack: codeql/cpp-all + extensible: summaryModel + data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance + - ["std", "weak_ptr", True, "weak_ptr", "(const weak_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "weak_ptr", "(weak_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "weak_ptr", "(const shared_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(const weak_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(const weak_ptr &)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(weak_ptr &&)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(weak_ptr &&)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(const shared_ptr &)", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "weak_ptr", True, "operator=", "(const shared_ptr &)", "", "Argument[*0]", "ReturnValue[*]", "value", "manual"] + - ["std", "weak_ptr", True, "lock", "", "", "Argument[-1]", "ReturnValue", "value", "manual"] + - ["std", "weak_ptr", True, "swap", "", "", "Argument[-1]", "Argument[*0]", "value", "manual"] + - ["std", "weak_ptr", True, "swap", "", "", "Argument[*0]", "Argument[-1]", "value", "manual"] + - ["std", "", False, "swap", "(weak_ptr &,weak_ptr &)", "", "Argument[*0]", "Argument[*1]", "value", "manual"] + - ["std", "", False, "swap", "(weak_ptr &,weak_ptr &)", "", "Argument[*1]", "Argument[*0]", "value", "manual"] diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll index bce936552768..04356ab03616 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll @@ -129,6 +129,14 @@ private predicate qualifierSourceImpl(RelevantNode n, Class c) { convert.getDerivedClass() = c and c.getABaseClass*().getAMemberFunction().isVirtual() ) + // or + // exists(Function f | + // f = n.(DataFlowPrivate::OutNode).getCall().getStaticCallSourceTarget() and + // n.(DataFlowPrivate::OutNode).getReturnKind().isNormalReturn() and + // n.(DataFlowPrivate::OutNode).getReturnKind().getIndirectionIndex() = 1 and + // f.hasGlobalOrStdOrBslName("make_unique") and + // c = f.(FunctionTemplateInstantiation).getTemplateArgument(0) + // ) } private module TrackVirtualDispatch { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll index 31931189003c..9929ec3c58d0 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll @@ -174,19 +174,6 @@ private class PointerOrArrayOrReferenceTypeIndirection extends Indirection insta } } -private class PointerWrapperTypeIndirection extends Indirection instanceof PointerWrapper { - PointerWrapperTypeIndirection() { baseType = PointerWrapper.super.getBaseType() } - - override predicate isAdditionalDereference(Instruction deref, Operand address) { - exists(CallInstruction call | - operandForFullyConvertedCall(getAUse(deref), call) and - this = - call.getStaticCallTarget().(Function).getClassAndName(["operator*", "operator->", "get"]) and - address = call.getThisArgumentOperand() - ) - } -} - private module IteratorIndirections { import semmle.code.cpp.models.interfaces.Iterator as Interfaces import semmle.code.cpp.models.implementations.Iterator as Iterator