Skip to content

Commit c19988a

Browse files
Update ImplicitSpecialMemberFunctions documentation
1 parent 67bb9d3 commit c19988a

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

cpp/common/src/codingstandards/cpp/types/ImplicitSpecialMemberFunctions.qll

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ private signature predicate constraint(Function mf);
4949
* - C_cannotHave{X} = set of all classes T for which "class T cannot have a {X}"
5050
* - C_mayHave{X} = not C_cannotHave{X}
5151
*
52+
* Note: We can find UDEF with certainty, just not IDEF.
53+
* - C_cannotHave{UDEC X} = not C_mustHave{UDEC X}, and
54+
* - C_mayHave{UDEC X} = C_mustHave{UDEC X}.
55+
* - This affects step 8 below.
56+
*
5257
* then we can find all cases we know to be deprecated via:
5358
* - Step 1: find C_mustHave{IDEF CC}, C_mustHave{IDEF CA}
5459
* - Step 2: find C_mustHave{UDEC CC}, C_mustHave{UDEC CA}, C_mustHave{UDEC D}
@@ -59,11 +64,16 @@ private signature predicate constraint(Function mf);
5964
* - Step 5: find C_cannotHave{IDEF CC}, C_cannotHave{IDEF CA}
6065
* - Step 6: find C_mayHave{IDEF CC}, C_mayHave{IDEF CA} (by negating the cannot sets)
6166
* - Step 7: find C_cannotHave{UDEC CC}, C_cannotHave{UDEC CA}, C_cannotHave{UDEC D}
62-
* - Step 8: find C_mayHave{UDEC CC}, C_mayHave{UDEC CA}, C_mayHave{UDEC D} (by negating the cannot sets)
67+
* - Step 8: find C_mayHave{UDEC CC}, C_mayHave{UDEC CA}, C_mayHave{UDEC D} -- these are actually known with certainty
6368
* - Step 9: All C' may be deprecated where C' in C_mayHave{IDEF CC} and (C' in C_mayHave{UDEC CA} or C' in C_mayHave{UDEC D})
6469
* - Step 10: All C' may be deprecated where C' in C_mayHave{IDEF CA} and (C' in C_mayHave{UDEC CC} or C' in C_mayHave{UDEC D})
6570
*
6671
* This is performed through the various instantiations of this module.
72+
*
73+
* This module assumes that a missing SpecialMember is neither `mustHave` or `cannotHave`. This is
74+
* the correct behavior for IDEF, but for UDEC, if no special member exists it should be part of the
75+
* `cannotHave` set. This is handled by later defining `C_mayHave{UDEC X} = C_mustHave{UDEC X}`,
76+
* which correctly handled the case where no X exists for that class.
6777
*/
6878
private module ClassesWhere<constraint/1 pred, SpecialMember Member> {
6979
final class FinalClass = Class;
@@ -121,15 +131,9 @@ private class CMayHaveIdefCA =
121131
* Step 7: find C_cannotHave{UDEC CC}, C_cannotHave{UDEC CA}, C_cannotHave{UDEC D}
122132
* Step 8: find C_mayHave{UDEC CC}, C_mayHave{UDEC CA}, C_mayHave{UDEC D} (by negating the cannot sets)
123133
*
124-
* In our case, `ClassesWhere<...>` performs steps 7 and 8 together via `NotMatching`.
134+
* As noted earlier, we know C_mayHave{UDEC X} with certainty. If there is no X in the database, then
135+
* it is not user-declared.
125136
*/
126-
//private class CMayHaveUdecCC = ClassesWhere<mustNotBeUserDeclared/1, CopyConstructor>::NotMatching;
127-
//
128-
//private class CMayHaveUdecCA =
129-
// ClassesWhere<mustNotBeUserDeclared/1, CopyAssignmentOperator>::NotMatching;
130-
//
131-
//private class CMayHaveUdecD = ClassesWhere<mustBeUserDeclared/1, Destructor>::Matching;
132-
// These are actually 100% known. If there is no dtor, it is not user declared.
133137
private class CMayHaveUdecCC = CMustHaveUdecCC;
134138

135139
private class CMayHaveUdecCA = CMustHaveUdecCA;

0 commit comments

Comments
 (0)