From 971456c725db04312abee65ee111c8e62eec5f8c Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Wed, 14 Jun 2023 13:18:29 -0400 Subject: [PATCH 1/3] C++: add a test for self-valued iterators --- .../dataflow/dataflow-tests/self-Iterator.cpp | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp new file mode 100644 index 00000000000..c02644d3f10 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp @@ -0,0 +1,21 @@ +#include "../../../include/iterator.h" +int source(); + +template +void sink(T); + +template<> struct std::iterator_traits +{ // get traits from integer type + typedef std::input_iterator_tag iterator_category; + typedef unsigned long value_type; + typedef unsigned long difference_type; + typedef unsigned long distance_type; + typedef unsigned long * pointer; + typedef unsigned long& reference; +}; + + +int test() { + unsigned long x = source(); + sink(x); // $ ast MISSING: ir +} \ No newline at end of file From 952dbd69e928b3204738a2a83f32b0517632ca90 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 20 Jun 2023 12:58:11 +0100 Subject: [PATCH 2/3] C++: Default to one indirection in the case of self iterators. --- .../cpp/ir/dataflow/internal/SsaInternalsCommon.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index d8571b8b74a..356a02e1cf9 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -117,6 +117,16 @@ private int countIndirections(Type t) { else ( result = any(Indirection ind | ind.getType() = t).getNumberOfIndirections() or + // If there is an indirection for the type, but we cannot count the number of indirections + // it means we couldn't reach a non-indirection type by stripping off indirections. This + // can occur if an iterator specifies itself as the value type. In this case we default to + // 1 indirection fore the type. + exists(Indirection ind | + ind.getType() = t and + not exists(ind.getNumberOfIndirections()) and + result = 1 + ) + or not exists(Indirection ind | ind.getType() = t) and result = 0 ) From 2b0282ca1255bcba465ce7769d9e52f4e960a00d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 20 Jun 2023 12:58:17 +0100 Subject: [PATCH 3/3] C++: Accept test changes. --- .../library-tests/dataflow/dataflow-tests/self-Iterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp index c02644d3f10..cac7f222c30 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self-Iterator.cpp @@ -17,5 +17,5 @@ template<> struct std::iterator_traits int test() { unsigned long x = source(); - sink(x); // $ ast MISSING: ir + sink(x); // $ ast ir } \ No newline at end of file