[mlir][acc] Introduce MappableType interface (#122146)
[llvm-project.git] / clang-tools-extra / docs / clang-tidy / checks / bugprone / easily-swappable-parameters.rst
blob47970bfbbc400a644c82697bfd257be6a8c8d436
1 .. title:: clang-tidy - bugprone-easily-swappable-parameters
3 bugprone-easily-swappable-parameters
4 ====================================
6 Finds function definitions where parameters of convertible types follow each
7 other directly, making call sites prone to calling the function with
8 swapped (or badly ordered) arguments.
10 .. code-block:: c++
12     void drawPoint(int X, int Y) { /* ... */ }
13     FILE *open(const char *Dir, const char *Name, Flags Mode) { /* ... */ }
15 A potential call like ``drawPoint(-2, 5)`` or ``openPath("a.txt", "tmp", Read)``
16 is perfectly legal from the language's perspective, but might not be what the
17 developer of the function intended.
19 More elaborate and type-safe constructs, such as opaque typedefs or strong
20 types should be used instead, to prevent a mistaken order of arguments.
22 .. code-block:: c++
24     struct Coord2D { int X; int Y; };
25     void drawPoint(const Coord2D Pos) { /* ... */ }
27     FILE *open(const Path &Dir, const Filename &Name, Flags Mode) { /* ... */ }
29 Due to the potentially elaborate refactoring and API-breaking that is necessary
30 to strengthen the type safety of a project, no automatic fix-its are offered.
32 Options
33 -------
35 Extension/relaxation options
36 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38 Relaxation (or extension) options can be used to broaden the scope of the
39 analysis and fine-tune the enabling of more mixes between types.
40 Some mixes may depend on coding style or preference specific to a project,
41 however, it should be noted that enabling *all* of these relaxations model the
42 way of mixing at call sites the most.
43 These options are expected to make the check report for more functions, and
44 report longer mixable ranges.
46 .. option:: QualifiersMix
48     Whether to consider parameters of some *cvr-qualified* ``T`` and a
49     differently *cvr-qualified* ``T`` (i.e. ``T`` and ``const T``, ``const T``
50     and ``volatile T``, etc.) mixable between one another.
51     If `false`, the check will consider differently qualified types unmixable.
52     `True` turns the warnings on.
53     Defaults to `false`.
55     The following example produces a diagnostic only if `QualifiersMix` is
56     enabled:
58     .. code-block:: c++
60         void *memcpy(const void *Destination, void *Source, std::size_t N) { /* ... */ }
62 .. option:: ModelImplicitConversions
64     Whether to consider parameters of type ``T`` and ``U`` mixable if there
65     exists an implicit conversion from ``T`` to ``U`` and ``U`` to ``T``.
66     If `false`, the check will not consider implicitly convertible types for
67     mixability.
68     `True` turns warnings for implicit conversions on.
69     Defaults to `true`.
71     The following examples produce a diagnostic only if
72     `ModelImplicitConversions` is enabled:
74     .. code-block:: c++
76         void fun(int Int, double Double) { /* ... */ }
77         void compare(const char *CharBuf, std::string String) { /* ... */ }
79     .. note::
81         Changing the qualifiers of an expression's type (e.g. from ``int`` to
82         ``const int``) is defined as an *implicit conversion* in the C++
83         Standard.
84         However, the check separates this decision-making on the mixability of
85         differently qualified types based on whether `QualifiersMix` was
86         enabled.
88         For example, the following code snippet will only produce a diagnostic
89         if **both** `QualifiersMix` and `ModelImplicitConversions` are enabled:
91         .. code-block:: c++
93             void fun2(int Int, const double Double) { /* ... */ }
95 Filtering options
96 ^^^^^^^^^^^^^^^^^
98 Filtering options can be used to lessen the size of the diagnostics emitted by
99 the checker, whether the aim is to ignore certain constructs or dampen the
100 noisiness.
102 .. option:: MinimumLength
104     The minimum length required from an adjacent parameter sequence to be
105     diagnosed.
106     Defaults to `2`.
107     Might be any positive integer greater or equal to `2`.
108     If `0` or `1` is given, the default value `2` will be used instead.
110     For example, if `3` is specified, the examples above will not be matched.
112 .. option:: IgnoredParameterNames
114     The list of parameter **names** that should never be considered part of a
115     swappable adjacent parameter sequence.
116     The value is a `;`-separated list of names.
117     To ignore unnamed parameters, add `""` to the list verbatim (not the
118     empty string, but the two quotes, potentially escaped!).
119     **This option is case-sensitive!**
121     By default, the following parameter names, and their Uppercase-initial
122     variants are ignored:
123     `""` (unnamed parameters), `iterator`, `begin`, `end`, `first`, `last`,
124     `lhs`, `rhs`.
126 .. option:: IgnoredParameterTypeSuffixes
128     The list of parameter **type name suffixes** that should never be
129     considered part of a swappable adjacent parameter sequence.
130     Parameters which type, as written in the source code, end with an element
131     of this option will be ignored.
132     The value is a `;`-separated list of names.
133     **This option is case-sensitive!**
135     By default, the following, and their lowercase-initial variants are ignored:
136     `bool`, `It`, `Iterator`, `InputIt`, `ForwardIt`, `BidirIt`, `RandomIt`,
137     `random_iterator`, `ReverseIt`, `reverse_iterator`,
138     `reverse_const_iterator`, `RandomIt`, `random_iterator`, `ReverseIt`,
139     `reverse_iterator`, `reverse_const_iterator`, `Const_Iterator`,
140     `ConstIterator`, `const_reverse_iterator`, `ConstReverseIterator`.
141     In addition, `_Bool` (but not `_bool`) is also part of the default value.
143 .. option:: SuppressParametersUsedTogether
145     Suppresses diagnostics about parameters that are used together or in a
146     similar fashion inside the function's body.
147     Defaults to `true`.
148     Specifying `false` will turn off the heuristics.
150     Currently, the following heuristics are implemented which will suppress the
151     warning about the parameter pair involved:
153     * The parameters are used in the same expression, e.g. ``f(a, b)`` or
154       ``a < b``.
155     * The parameters are further passed to the same function to the same
156       parameter of that function, of the same overload.
157       E.g. ``f(a, 1)`` and ``f(b, 2)`` to some ``f(T, int)``.
159       .. note::
161         The check does not perform path-sensitive analysis, and as such,
162         "same function" in this context means the same function declaration.
163         If the same member function of a type on two distinct instances are
164         called with the parameters, it will still be regarded as
165         "same function".
167     * The same member field is accessed, or member method is called of the
168       two parameters, e.g. ``a.foo()`` and ``b.foo()``.
169     * Separate ``return`` statements return either of the parameters on
170       different code paths.
172 .. option:: NamePrefixSuffixSilenceDissimilarityTreshold
174     The number of characters two parameter names might be different on *either*
175     the head or the tail end with the rest of the name the same so that the
176     warning about the two parameters are silenced.
177     Defaults to `1`.
178     Might be any positive integer.
179     If `0`, the filtering heuristic based on the parameters' names is turned
180     off.
182     This option can be used to silence warnings about parameters where the
183     naming scheme indicates that the order of those parameters do not matter.
185     For example, the parameters ``LHS`` and ``RHS`` are 1-dissimilar suffixes
186     of each other: ``L`` and ``R`` is the different character, while ``HS``
187     is the common suffix.
188     Similarly, parameters ``text1, text2, text3`` are 1-dissimilar prefixes
189     of each other, with the numbers at the end being the dissimilar part.
190     If the value is at least `1`, such cases will not be reported.
193 Limitations
194 -----------
196 **This check is designed to check function signatures!**
198 The check does not investigate functions that are generated by the compiler
199 in a context that is only determined from a call site.
200 These cases include variadic functions, functions in C code that do not have
201 an argument list, and C++ template instantiations.
202 Most of these cases, which are otherwise swappable from a caller's standpoint,
203 have no way of getting "fixed" at the definition point.
204 In the case of C++ templates, only primary template definitions and explicit
205 specializations are matched and analyzed.
207 None of the following cases produce a diagnostic:
209 .. code-block:: c++
211     int printf(const char *Format, ...) { /* ... */ }
212     int someOldCFunction() { /* ... */ }
214     template <typename T, typename U>
215     int add(T X, U Y) { return X + Y };
217     void theseAreNotWarnedAbout() {
218         printf("%d %d\n", 1, 2);   // Two ints passed, they could be swapped.
219         someOldCFunction(1, 2, 3); // Similarly, multiple ints passed.
221         add(1, 2); // Instantiates 'add<int, int>', but that's not a user-defined function.
222     }
224 Due to the limitation above, parameters which type are further dependent upon
225 template instantiations to *prove* that they mix with another parameter's is
226 not diagnosed.
228 .. code-block:: c++
230     template <typename T>
231     struct Vector {
232       typedef T element_type;
233     };
235     // Diagnosed: Explicit instantiation was done by the user, we can prove it
236     // is the same type.
237     void instantiated(int A, Vector<int>::element_type B) { /* ... */ }
239     // Diagnosed: The two parameter types are exactly the same.
240     template <typename T>
241     void exact(typename Vector<T>::element_type A,
242                typename Vector<T>::element_type B) { /* ... */ }
244     // Skipped: The two parameters are both 'T' but we cannot prove this
245     // without actually instantiating.
246     template <typename T>
247     void falseNegative(T A, typename Vector<T>::element_type B) { /* ... */ }
249 In the context of *implicit conversions* (when `ModelImplicitConversions` is
250 enabled), the modelling performed by the check
251 warns if the parameters are swappable and the swapped order matches implicit
252 conversions.
253 It does not model whether there exists an unrelated third type from which
254 *both* parameters can be given in a function call.
255 This means that in the following example, even while ``strs()`` clearly carries
256 the possibility to be called with swapped arguments (as long as the arguments
257 are string literals), will not be warned about.
259 .. code-block:: c++
261     struct String {
262         String(const char *Buf);
263     };
265     struct StringView {
266         StringView(const char *Buf);
267         operator const char *() const;
268     };
270     // Skipped: Directly swapping expressions of the two type cannot mix.
271     // (Note: StringView -> const char * -> String would be **two**
272     // user-defined conversions, which is disallowed by the language.)
273     void strs(String Str, StringView SV) { /* ... */ }
275     // Diagnosed: StringView implicitly converts to and from a buffer.
276     void cStr(StringView SV, const char *Buf() { /* ... */ }