From 61c315d74b6b7cf496573ca1f4d4bd36d3264da3 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 7 Feb 2022 12:56:59 -0500 Subject: [PATCH 1/3] C++: test for explicit template copy constructor --- .../generated_copy/assign.expected | 1 + .../special_members/generated_copy/copy.cpp | 18 ++++++++++++++++++ .../generated_copy/ctor.expected | 1 + .../generated_copy/functions.expected | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected b/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected index eec36e7e39c3..28c90cb5233a 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/assign.expected @@ -11,6 +11,7 @@ | difference::Base | can | does NOT | have implicit copy assignment | | difference::OnlyAssign | can | does | have implicit copy assignment | | difference::OnlyCtor | can NOT | does NOT | have implicit copy assignment | +| instantiated_explicit_ctor::Wrapper | can | does | have implicit copy assignment | | moves::MoveAssign | can NOT | does NOT | have implicit copy assignment | | moves::MoveCtor | can NOT | does NOT | have implicit copy assignment | | private_cc::C | can | does NOT | have implicit copy assignment | diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp b/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp index 8d68cfdc09e5..fac52670bca6 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp +++ b/cpp/ql/test/library-tests/special_members/generated_copy/copy.cpp @@ -131,3 +131,21 @@ namespace difference { class OnlyAssign : Base { }; } + +namespace instantiated_explicit_ctor { + template + class Wrapper { + public: + Wrapper(Wrapper &other) { + m_t = other.m_t; + } + + Wrapper() { + m_t = 0; + } + private: + T m_t; + }; + + Wrapper wrapped_int; +} diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected index 22745978bf89..cf7a4c517602 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected @@ -11,6 +11,7 @@ | difference::Base | can | does NOT | have implicit copy constructor | | difference::OnlyAssign | can NOT | does NOT | have implicit copy constructor | | difference::OnlyCtor | can | does | have implicit copy constructor | +| instantiated_explicit_ctor::Wrapper | can | does | have implicit copy constructor | | moves::MoveAssign | can NOT | does NOT | have implicit copy constructor | | moves::MoveCtor | can NOT | does NOT | have implicit copy constructor | | private_cc::C | can | does NOT | have implicit copy constructor | diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected b/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected index 22282641b373..434b950e35c3 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/functions.expected @@ -86,5 +86,9 @@ | copy.cpp:131:9:131:9 | OnlyAssign | deleted | | | copy.cpp:131:9:131:9 | operator= | | | | copy.cpp:131:9:131:9 | operator= | | | +| copy.cpp:137:9:137:9 | operator= | | | +| copy.cpp:139:5:139:11 | Wrapper | | | +| copy.cpp:143:5:143:5 | Wrapper | | | +| copy.cpp:143:5:143:11 | Wrapper | | | | file://:0:0:0:0 | operator= | | | | file://:0:0:0:0 | operator= | | | From 56caa5dfd6b5b06bad16b1552a1b2761669f1eb1 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 7 Feb 2022 14:26:28 -0500 Subject: [PATCH 2/3] C++: fix hasImplicitCopyConstructor for templates Fixes some cases in instantiations of templates with manually written copy constructors or copy assignment operators where hasImplicitCopyConstructor would incorrectly hold --- cpp/ql/lib/semmle/code/cpp/Class.qll | 22 +++++++++++++++++++ .../generated_copy/ctor.expected | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Class.qll b/cpp/ql/lib/semmle/code/cpp/Class.qll index 64819a5e945b..012691aa7287 100644 --- a/cpp/ql/lib/semmle/code/cpp/Class.qll +++ b/cpp/ql/lib/semmle/code/cpp/Class.qll @@ -286,6 +286,16 @@ class Class extends UserType { not this.implicitCopyConstructorDeleted() and forall(CopyConstructor cc | cc = this.getAMemberFunction() | cc.isCompilerGenerated() and not cc.isDeleted() + ) and + ( + not this instanceof ClassTemplateInstantiation + or + this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyConstructor() + ) and + ( + not this instanceof PartialClassTemplateSpecialization + or + this.(PartialClassTemplateSpecialization).getPrimaryTemplate().hasImplicitCopyConstructor() ) } @@ -301,6 +311,18 @@ class Class extends UserType { not this.implicitCopyAssignmentOperatorDeleted() and forall(CopyAssignmentOperator ca | ca = this.getAMemberFunction() | ca.isCompilerGenerated() and not ca.isDeleted() + ) and + ( + not this instanceof ClassTemplateInstantiation + or + this.(ClassTemplateInstantiation).getTemplate().hasImplicitCopyAssignmentOperator() + ) and + ( + not this instanceof PartialClassTemplateSpecialization + or + this.(PartialClassTemplateSpecialization) + .getPrimaryTemplate() + .hasImplicitCopyAssignmentOperator() ) } diff --git a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected index cf7a4c517602..90a3f811e5dc 100644 --- a/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected +++ b/cpp/ql/test/library-tests/special_members/generated_copy/ctor.expected @@ -11,7 +11,7 @@ | difference::Base | can | does NOT | have implicit copy constructor | | difference::OnlyAssign | can NOT | does NOT | have implicit copy constructor | | difference::OnlyCtor | can | does | have implicit copy constructor | -| instantiated_explicit_ctor::Wrapper | can | does | have implicit copy constructor | +| instantiated_explicit_ctor::Wrapper | can | does NOT | have implicit copy constructor | | moves::MoveAssign | can NOT | does NOT | have implicit copy constructor | | moves::MoveCtor | can NOT | does NOT | have implicit copy constructor | | private_cc::C | can | does NOT | have implicit copy constructor | From 1e2cc4fca8cf0ed33abcf9c8f2cc9355b14ff19e Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Thu, 10 Mar 2022 15:26:24 -0500 Subject: [PATCH 3/3] C++: change note for template implicit copy ops --- cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md diff --git a/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md b/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md new file mode 100644 index 000000000000..fe2afba65684 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-03-10-template-implicit-copy.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `hasImplicitCopyConstructor` and `hasImplicitCopyAssignmentOperator` now correctly handle implicitly-deleted operators in templates. \ No newline at end of file