|
| 1 | +// Trivial class - no virtual functions, trivial special members |
| 2 | +struct TrivialClass { |
| 3 | + int m1; |
| 4 | +}; |
| 5 | + |
| 6 | +// Class with virtual member function |
| 7 | +struct VirtualMemberClass { |
| 8 | + int m1; |
| 9 | + virtual void f1() {} |
| 10 | +}; |
| 11 | + |
| 12 | +// Class with virtual destructor |
| 13 | +struct VirtualDestructorClass { |
| 14 | + int m1; |
| 15 | + virtual ~VirtualDestructorClass() = default; |
| 16 | +}; |
| 17 | + |
| 18 | +// Class with user-defined (non-trivial) copy constructor |
| 19 | +struct NonTrivialCopyClass { |
| 20 | + int m1; |
| 21 | + NonTrivialCopyClass() = default; |
| 22 | + NonTrivialCopyClass(const NonTrivialCopyClass &other) {} |
| 23 | +}; |
| 24 | + |
| 25 | +// Class with user-defined (non-trivial) move constructor |
| 26 | +struct NonTrivialMoveClass { |
| 27 | + int m1; |
| 28 | + NonTrivialMoveClass() = default; |
| 29 | + NonTrivialMoveClass(NonTrivialMoveClass &&other) {} |
| 30 | +}; |
| 31 | + |
| 32 | +// Class with user-defined (non-trivial) copy assignment operator |
| 33 | +struct NonTrivialCopyAssignClass { |
| 34 | + int m1; |
| 35 | + NonTrivialCopyAssignClass &operator=(const NonTrivialCopyAssignClass &other) { |
| 36 | + return *this; |
| 37 | + } |
| 38 | +}; |
| 39 | + |
| 40 | +// Class with user-defined (non-trivial) move assignment operator |
| 41 | +struct NonTrivialMoveAssignClass { |
| 42 | + int m1; |
| 43 | + NonTrivialMoveAssignClass &operator=(NonTrivialMoveAssignClass &&other) { |
| 44 | + return *this; |
| 45 | + } |
| 46 | +}; |
| 47 | + |
| 48 | +// Class with user-defined (non-trivial) destructor |
| 49 | +struct NonTrivialDestructorClass { |
| 50 | + ~NonTrivialDestructorClass() {} |
| 51 | +}; |
| 52 | + |
| 53 | +// Derived class inheriting virtual |
| 54 | +struct DerivedFromVirtual : public VirtualMemberClass { |
| 55 | + void f1() override {} |
| 56 | +}; |
| 57 | + |
| 58 | +// Class with multiple inappropriate properties |
| 59 | +struct MultipleIssuesClass { |
| 60 | + virtual void f1() {} |
| 61 | + MultipleIssuesClass() = default; |
| 62 | + MultipleIssuesClass(const MultipleIssuesClass &) {} |
| 63 | + ~MultipleIssuesClass() {} |
| 64 | +}; |
| 65 | + |
| 66 | +// Class with defaulted special members (trivial) |
| 67 | +struct DefaultedClass { |
| 68 | + int m1; |
| 69 | + DefaultedClass() = default; |
| 70 | + DefaultedClass(const DefaultedClass &) = default; |
| 71 | + DefaultedClass(DefaultedClass &&) = default; |
| 72 | + DefaultedClass &operator=(const DefaultedClass &) = default; |
| 73 | + DefaultedClass &operator=(DefaultedClass &&) = default; |
| 74 | + ~DefaultedClass() = default; |
| 75 | +}; |
| 76 | + |
| 77 | +// A typedef for an inappropriate type |
| 78 | +using VirtualAlias = VirtualMemberClass; |
| 79 | + |
| 80 | +// User-defined variadic function |
| 81 | +int variadic_func(int p1, ...); |
| 82 | + |
| 83 | +void f() { |
| 84 | + variadic_func(0, 42); // COMPLIANT |
| 85 | + variadic_func(0, 3.14); // COMPLIANT |
| 86 | + variadic_func(0, (void *)nullptr); // COMPLIANT |
| 87 | + |
| 88 | + variadic_func(0, TrivialClass()); // COMPLIANT |
| 89 | + variadic_func(0, DefaultedClass()); // COMPLIANT |
| 90 | + variadic_func(0, VirtualMemberClass()); // NON_COMPLIANT |
| 91 | + variadic_func(0, VirtualDestructorClass()); // NON_COMPLIANT |
| 92 | + variadic_func(0, NonTrivialCopyClass()); // NON_COMPLIANT |
| 93 | + variadic_func(0, NonTrivialMoveClass()); // NON_COMPLIANT |
| 94 | + variadic_func(0, NonTrivialCopyAssignClass()); // NON_COMPLIANT |
| 95 | + variadic_func(0, NonTrivialMoveAssignClass()); // NON_COMPLIANT |
| 96 | + variadic_func(0, NonTrivialDestructorClass()); // NON_COMPLIANT |
| 97 | + variadic_func(0, DerivedFromVirtual()); // NON_COMPLIANT |
| 98 | + variadic_func(0, MultipleIssuesClass()); // NON_COMPLIANT |
| 99 | + variadic_func(0, VirtualAlias()); // NON_COMPLIANT |
| 100 | + variadic_func(0, VirtualMemberClass()); // NON_COMPLIANT |
| 101 | + |
| 102 | + variadic_func(0, TrivialClass(), VirtualMemberClass()); // NON_COMPLIANT |
| 103 | +} |
| 104 | + |
| 105 | +void test_unevaluated_context() { |
| 106 | + sizeof(variadic_func(0, VirtualMemberClass())); // COMPLIANT |
| 107 | +} |
| 108 | + |
| 109 | +// Parameter pack is not ellipsis |
| 110 | +template <typename... Args> void parameter_pack_func(Args... p1) {} |
| 111 | + |
| 112 | +void test_parameter_pack() { |
| 113 | + VirtualMemberClass l1; |
| 114 | + NonTrivialCopyClass l2; |
| 115 | + parameter_pack_func(l1, l2); // COMPLIANT |
| 116 | +} |
| 117 | + |
| 118 | +void variadic_take_objects(VirtualMemberClass v, ...); |
| 119 | +void test_named_parameter_of_variadic_function() { |
| 120 | + variadic_take_objects(VirtualMemberClass()); // COMPLIANT |
| 121 | + variadic_take_objects(VirtualMemberClass(), |
| 122 | + VirtualMemberClass()); // NON_COMPLIANT |
| 123 | +} |
0 commit comments