xref: /llvm-project/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (revision f71ffd3b735b4d6ae3c12be1806cdd6205b3b378)
1 //===--- EasilySwappableParametersCheck.cpp - clang-tidy ------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "EasilySwappableParametersCheck.h"
10 #include "../utils/OptionsUtils.h"
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/RecursiveASTVisitor.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "clang/Lex/Lexer.h"
15 #include "llvm/ADT/SmallSet.h"
16 
17 #define DEBUG_TYPE "EasilySwappableParametersCheck"
18 #include "llvm/Support/Debug.h"
19 #include <optional>
20 
21 namespace optutils = clang::tidy::utils::options;
22 
23 /// The default value for the MinimumLength check option.
24 static constexpr std::size_t DefaultMinimumLength = 2;
25 
26 /// The default value for ignored parameter names.
27 static constexpr llvm::StringLiteral DefaultIgnoredParameterNames = "\"\";"
28                                                                     "iterator;"
29                                                                     "Iterator;"
30                                                                     "begin;"
31                                                                     "Begin;"
32                                                                     "end;"
33                                                                     "End;"
34                                                                     "first;"
35                                                                     "First;"
36                                                                     "last;"
37                                                                     "Last;"
38                                                                     "lhs;"
39                                                                     "LHS;"
40                                                                     "rhs;"
41                                                                     "RHS";
42 
43 /// The default value for ignored parameter type suffixes.
44 static constexpr llvm::StringLiteral DefaultIgnoredParameterTypeSuffixes =
45     "bool;"
46     "Bool;"
47     "_Bool;"
48     "it;"
49     "It;"
50     "iterator;"
51     "Iterator;"
52     "inputit;"
53     "InputIt;"
54     "forwardit;"
55     "ForwardIt;"
56     "bidirit;"
57     "BidirIt;"
58     "constiterator;"
59     "const_iterator;"
60     "Const_Iterator;"
61     "Constiterator;"
62     "ConstIterator;"
63     "RandomIt;"
64     "randomit;"
65     "random_iterator;"
66     "ReverseIt;"
67     "reverse_iterator;"
68     "reverse_const_iterator;"
69     "ConstReverseIterator;"
70     "Const_Reverse_Iterator;"
71     "const_reverse_iterator;"
72     "Constreverseiterator;"
73     "constreverseiterator";
74 
75 /// The default value for the QualifiersMix check option.
76 static constexpr bool DefaultQualifiersMix = false;
77 
78 /// The default value for the ModelImplicitConversions check option.
79 static constexpr bool DefaultModelImplicitConversions = true;
80 
81 /// The default value for suppressing diagnostics about parameters that are
82 /// used together.
83 static constexpr bool DefaultSuppressParametersUsedTogether = true;
84 
85 /// The default value for the NamePrefixSuffixSilenceDissimilarityTreshold
86 /// check option.
87 static constexpr std::size_t
88     DefaultNamePrefixSuffixSilenceDissimilarityTreshold = 1;
89 
90 using namespace clang::ast_matchers;
91 
92 namespace clang {
93 namespace tidy {
94 namespace bugprone {
95 
96 using TheCheck = EasilySwappableParametersCheck;
97 
98 namespace filter {
99 class SimilarlyUsedParameterPairSuppressor;
100 
101 static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node);
102 static inline bool
103 isSimilarlyUsedParameter(const SimilarlyUsedParameterPairSuppressor &Suppressor,
104                          const ParmVarDecl *Param1, const ParmVarDecl *Param2);
105 static bool prefixSuffixCoverUnderThreshold(std::size_t Threshold,
106                                             StringRef Str1, StringRef Str2);
107 } // namespace filter
108 
109 namespace model {
110 
111 /// The language features involved in allowing the mix between two parameters.
112 enum class MixFlags : unsigned char {
113   Invalid = 0, ///< Sentinel bit pattern. DO NOT USE!
114 
115   /// Certain constructs (such as pointers to noexcept/non-noexcept functions)
116   /// have the same CanonicalType, which would result in false positives.
117   /// During the recursive modelling call, this flag is set if a later diagnosed
118   /// canonical type equivalence should be thrown away.
119   WorkaroundDisableCanonicalEquivalence = 1,
120 
121   None = 2,           ///< Mix between the two parameters is not possible.
122   Trivial = 4,        ///< The two mix trivially, and are the exact same type.
123   Canonical = 8,      ///< The two mix because the types refer to the same
124                       /// CanonicalType, but we do not elaborate as to how.
125   TypeAlias = 16,     ///< The path from one type to the other involves
126                       /// desugaring type aliases.
127   ReferenceBind = 32, ///< The mix involves the binding power of "const &".
128   Qualifiers = 64,    ///< The mix involves change in the qualifiers.
129   ImplicitConversion = 128, ///< The mixing of the parameters is possible
130                             /// through implicit conversions between the types.
131 
132   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue =*/ImplicitConversion)
133 };
134 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
135 
136 /// Returns whether the SearchedFlag is turned on in the Data.
137 static inline bool hasFlag(MixFlags Data, MixFlags SearchedFlag) {
138   assert(SearchedFlag != MixFlags::Invalid &&
139          "can't be used to detect lack of all bits!");
140 
141   // "Data & SearchedFlag" would need static_cast<bool>() in conditions.
142   return (Data & SearchedFlag) == SearchedFlag;
143 }
144 
145 #ifndef NDEBUG
146 
147 // The modelling logic of this check is more complex than usual, and
148 // potentially hard to understand without the ability to see into the
149 // representation during the recursive descent. This debug code is only
150 // compiled in 'Debug' mode, or if LLVM_ENABLE_ASSERTIONS config is turned on.
151 
152 /// Formats the MixFlags enum into a useful, user-readable representation.
153 static inline std::string formatMixFlags(MixFlags F) {
154   if (F == MixFlags::Invalid)
155     return "#Inv!";
156 
157   SmallString<8> Str{"-------"};
158 
159   if (hasFlag(F, MixFlags::None))
160     // Shows the None bit explicitly, as it can be applied in the recursion
161     // even if other bits are set.
162     Str[0] = '!';
163   if (hasFlag(F, MixFlags::Trivial))
164     Str[1] = 'T';
165   if (hasFlag(F, MixFlags::Canonical))
166     Str[2] = 'C';
167   if (hasFlag(F, MixFlags::TypeAlias))
168     Str[3] = 't';
169   if (hasFlag(F, MixFlags::ReferenceBind))
170     Str[4] = '&';
171   if (hasFlag(F, MixFlags::Qualifiers))
172     Str[5] = 'Q';
173   if (hasFlag(F, MixFlags::ImplicitConversion))
174     Str[6] = 'i';
175 
176   if (hasFlag(F, MixFlags::WorkaroundDisableCanonicalEquivalence))
177     Str.append("(~C)");
178 
179   return Str.str().str();
180 }
181 
182 #endif // NDEBUG
183 
184 /// The results of the steps of an Implicit Conversion Sequence is saved in
185 /// an instance of this record.
186 ///
187 /// A ConversionSequence maps the steps of the conversion with a member for
188 /// each type involved in the conversion. Imagine going from a hypothetical
189 /// Complex class to projecting it to the real part as a const double.
190 ///
191 /// I.e., given:
192 ///
193 ///    struct Complex {
194 ///      operator double() const;
195 ///    };
196 ///
197 ///    void functionBeingAnalysed(Complex C, const double R);
198 ///
199 /// we will get the following sequence:
200 ///
201 /// (Begin=) Complex
202 ///
203 ///     The first standard conversion is a qualification adjustment.
204 /// (AfterFirstStandard=) const Complex
205 ///
206 ///     Then the user-defined conversion is executed.
207 /// (UDConvOp.ConversionOperatorResultType=) double
208 ///
209 ///     Then this 'double' is qualifier-adjusted to 'const double'.
210 /// (AfterSecondStandard=) double
211 ///
212 /// The conversion's result has now been calculated, so it ends here.
213 /// (End=) double.
214 ///
215 /// Explicit storing of Begin and End in this record is needed, because
216 /// getting to what Begin and End here are needs further resolution of types,
217 /// e.g. in the case of typedefs:
218 ///
219 ///     using Comp = Complex;
220 ///     using CD = const double;
221 ///     void functionBeingAnalysed2(Comp C, CD R);
222 ///
223 /// In this case, the user will be diagnosed with a potential conversion
224 /// between the two typedefs as written in the code, but to elaborate the
225 /// reasoning behind this conversion, we also need to show what the typedefs
226 /// mean. See FormattedConversionSequence towards the bottom of this file!
227 struct ConversionSequence {
228   enum UserDefinedConversionKind { UDCK_None, UDCK_Ctor, UDCK_Oper };
229 
230   struct UserDefinedConvertingConstructor {
231     const CXXConstructorDecl *Fun;
232     QualType ConstructorParameterType;
233     QualType UserDefinedType;
234   };
235 
236   struct UserDefinedConversionOperator {
237     const CXXConversionDecl *Fun;
238     QualType UserDefinedType;
239     QualType ConversionOperatorResultType;
240   };
241 
242   /// The type the conversion stared from.
243   QualType Begin;
244 
245   /// The intermediate type after the first Standard Conversion Sequence.
246   QualType AfterFirstStandard;
247 
248   /// The details of the user-defined conversion involved, as a tagged union.
249   union {
250     char None;
251     UserDefinedConvertingConstructor UDConvCtor;
252     UserDefinedConversionOperator UDConvOp;
253   };
254   UserDefinedConversionKind UDConvKind;
255 
256   /// The intermediate type after performing the second Standard Conversion
257   /// Sequence.
258   QualType AfterSecondStandard;
259 
260   /// The result type the conversion targeted.
261   QualType End;
262 
263   ConversionSequence() : None(0), UDConvKind(UDCK_None) {}
264   ConversionSequence(QualType From, QualType To)
265       : Begin(From), None(0), UDConvKind(UDCK_None), End(To) {}
266 
267   explicit operator bool() const {
268     return !AfterFirstStandard.isNull() || UDConvKind != UDCK_None ||
269            !AfterSecondStandard.isNull();
270   }
271 
272   /// Returns all the "steps" (non-unique and non-similar) types involved in
273   /// the conversion sequence. This method does **NOT** return Begin and End.
274   SmallVector<QualType, 4> getInvolvedTypesInSequence() const {
275     SmallVector<QualType, 4> Ret;
276     auto EmplaceIfDifferent = [&Ret](QualType QT) {
277       if (QT.isNull())
278         return;
279       if (Ret.empty())
280         Ret.emplace_back(QT);
281       else if (Ret.back() != QT)
282         Ret.emplace_back(QT);
283     };
284 
285     EmplaceIfDifferent(AfterFirstStandard);
286     switch (UDConvKind) {
287     case UDCK_Ctor:
288       EmplaceIfDifferent(UDConvCtor.ConstructorParameterType);
289       EmplaceIfDifferent(UDConvCtor.UserDefinedType);
290       break;
291     case UDCK_Oper:
292       EmplaceIfDifferent(UDConvOp.UserDefinedType);
293       EmplaceIfDifferent(UDConvOp.ConversionOperatorResultType);
294       break;
295     case UDCK_None:
296       break;
297     }
298     EmplaceIfDifferent(AfterSecondStandard);
299 
300     return Ret;
301   }
302 
303   /// Updates the steps of the conversion sequence with the steps from the
304   /// other instance.
305   ///
306   /// \note This method does not check if the resulting conversion sequence is
307   /// sensible!
308   ConversionSequence &update(const ConversionSequence &RHS) {
309     if (!RHS.AfterFirstStandard.isNull())
310       AfterFirstStandard = RHS.AfterFirstStandard;
311     switch (RHS.UDConvKind) {
312     case UDCK_Ctor:
313       UDConvKind = UDCK_Ctor;
314       UDConvCtor = RHS.UDConvCtor;
315       break;
316     case UDCK_Oper:
317       UDConvKind = UDCK_Oper;
318       UDConvOp = RHS.UDConvOp;
319       break;
320     case UDCK_None:
321       break;
322     }
323     if (!RHS.AfterSecondStandard.isNull())
324       AfterSecondStandard = RHS.AfterSecondStandard;
325 
326     return *this;
327   }
328 
329   /// Sets the user-defined conversion to the given constructor.
330   void setConversion(const UserDefinedConvertingConstructor &UDCC) {
331     UDConvKind = UDCK_Ctor;
332     UDConvCtor = UDCC;
333   }
334 
335   /// Sets the user-defined conversion to the given operator.
336   void setConversion(const UserDefinedConversionOperator &UDCO) {
337     UDConvKind = UDCK_Oper;
338     UDConvOp = UDCO;
339   }
340 
341   /// Returns the type in the conversion that's formally "in our hands" once
342   /// the user-defined conversion is executed.
343   QualType getTypeAfterUserDefinedConversion() const {
344     switch (UDConvKind) {
345     case UDCK_Ctor:
346       return UDConvCtor.UserDefinedType;
347     case UDCK_Oper:
348       return UDConvOp.ConversionOperatorResultType;
349     case UDCK_None:
350       return {};
351     }
352     llvm_unreachable("Invalid UDConv kind.");
353   }
354 
355   const CXXMethodDecl *getUserDefinedConversionFunction() const {
356     switch (UDConvKind) {
357     case UDCK_Ctor:
358       return UDConvCtor.Fun;
359     case UDCK_Oper:
360       return UDConvOp.Fun;
361     case UDCK_None:
362       return {};
363     }
364     llvm_unreachable("Invalid UDConv kind.");
365   }
366 
367   /// Returns the SourceRange in the text that corresponds to the interesting
368   /// part of the user-defined conversion. This is either the parameter type
369   /// in a converting constructor, or the conversion result type in a conversion
370   /// operator.
371   SourceRange getUserDefinedConversionHighlight() const {
372     switch (UDConvKind) {
373     case UDCK_Ctor:
374       return UDConvCtor.Fun->getParamDecl(0)->getSourceRange();
375     case UDCK_Oper:
376       // getReturnTypeSourceRange() does not work for CXXConversionDecls as the
377       // returned type is physically behind the declaration's name ("operator").
378       if (const FunctionTypeLoc FTL = UDConvOp.Fun->getFunctionTypeLoc())
379         if (const TypeLoc RetLoc = FTL.getReturnLoc())
380           return RetLoc.getSourceRange();
381       return {};
382     case UDCK_None:
383       return {};
384     }
385     llvm_unreachable("Invalid UDConv kind.");
386   }
387 };
388 
389 /// Contains the metadata for the mixability result between two types,
390 /// independently of which parameters they were calculated from.
391 struct MixData {
392   /// The flag bits of the mix indicating what language features allow for it.
393   MixFlags Flags = MixFlags::Invalid;
394 
395   /// A potentially calculated common underlying type after desugaring, that
396   /// both sides of the mix can originate from.
397   QualType CommonType;
398 
399   /// The steps an implicit conversion performs to get from one type to the
400   /// other.
401   ConversionSequence Conversion, ConversionRTL;
402 
403   /// True if the MixData was specifically created with only a one-way
404   /// conversion modelled.
405   bool CreatedFromOneWayConversion = false;
406 
407   MixData(MixFlags Flags) : Flags(Flags) {}
408   MixData(MixFlags Flags, QualType CommonType)
409       : Flags(Flags), CommonType(CommonType) {}
410   MixData(MixFlags Flags, ConversionSequence Conv)
411       : Flags(Flags), Conversion(Conv), CreatedFromOneWayConversion(true) {}
412   MixData(MixFlags Flags, ConversionSequence LTR, ConversionSequence RTL)
413       : Flags(Flags), Conversion(LTR), ConversionRTL(RTL) {}
414   MixData(MixFlags Flags, QualType CommonType, ConversionSequence LTR,
415           ConversionSequence RTL)
416       : Flags(Flags), CommonType(CommonType), Conversion(LTR),
417         ConversionRTL(RTL) {}
418 
419   void sanitize() {
420     assert(Flags != MixFlags::Invalid && "sanitize() called on invalid bitvec");
421 
422     MixFlags CanonicalAndWorkaround =
423         MixFlags::Canonical | MixFlags::WorkaroundDisableCanonicalEquivalence;
424     if ((Flags & CanonicalAndWorkaround) == CanonicalAndWorkaround) {
425       // A workaround for too eagerly equivalent canonical types was requested,
426       // and a canonical equivalence was proven. Fulfill the request and throw
427       // this result away.
428       Flags = MixFlags::None;
429       return;
430     }
431 
432     if (hasFlag(Flags, MixFlags::None)) {
433       // If anywhere down the recursion a potential mix "path" is deemed
434       // impossible, throw away all the other bits because the mix is not
435       // possible.
436       Flags = MixFlags::None;
437       return;
438     }
439 
440     if (Flags == MixFlags::Trivial)
441       return;
442 
443     if (static_cast<bool>(Flags ^ MixFlags::Trivial))
444       // If the mix involves somewhere trivial equivalence but down the
445       // recursion other bit(s) were set, remove the trivial bit, as it is not
446       // trivial.
447       Flags &= ~MixFlags::Trivial;
448 
449     bool ShouldHaveImplicitConvFlag = false;
450     if (CreatedFromOneWayConversion && Conversion)
451       ShouldHaveImplicitConvFlag = true;
452     else if (!CreatedFromOneWayConversion && Conversion && ConversionRTL)
453       // Only say that we have implicit conversion mix possibility if it is
454       // bidirectional. Otherwise, the compiler would report an *actual* swap
455       // at a call site...
456       ShouldHaveImplicitConvFlag = true;
457 
458     if (ShouldHaveImplicitConvFlag)
459       Flags |= MixFlags::ImplicitConversion;
460     else
461       Flags &= ~MixFlags::ImplicitConversion;
462   }
463 
464   bool isValid() const { return Flags >= MixFlags::None; }
465 
466   bool indicatesMixability() const { return Flags > MixFlags::None; }
467 
468   /// Add the specified flag bits to the flags.
469   MixData operator|(MixFlags EnableFlags) const {
470     if (CreatedFromOneWayConversion) {
471       MixData M{Flags | EnableFlags, Conversion};
472       M.CommonType = CommonType;
473       return M;
474     }
475     return {Flags | EnableFlags, CommonType, Conversion, ConversionRTL};
476   }
477 
478   /// Add the specified flag bits to the flags.
479   MixData &operator|=(MixFlags EnableFlags) {
480     Flags |= EnableFlags;
481     return *this;
482   }
483 
484   template <class F> MixData withCommonTypeTransformed(F &&Func) const {
485     if (CommonType.isNull())
486       return *this;
487 
488     QualType NewCommonType = Func(CommonType);
489 
490     if (CreatedFromOneWayConversion) {
491       MixData M{Flags, Conversion};
492       M.CommonType = NewCommonType;
493       return M;
494     }
495 
496     return {Flags, NewCommonType, Conversion, ConversionRTL};
497   }
498 };
499 
500 /// A named tuple that contains the information for a mix between two concrete
501 /// parameters.
502 struct Mix {
503   const ParmVarDecl *First, *Second;
504   MixData Data;
505 
506   Mix(const ParmVarDecl *F, const ParmVarDecl *S, MixData Data)
507       : First(F), Second(S), Data(std::move(Data)) {}
508 
509   void sanitize() { Data.sanitize(); }
510   MixFlags flags() const { return Data.Flags; }
511   bool flagsValid() const { return Data.isValid(); }
512   bool mixable() const { return Data.indicatesMixability(); }
513   QualType commonUnderlyingType() const { return Data.CommonType; }
514   const ConversionSequence &leftToRightConversionSequence() const {
515     return Data.Conversion;
516   }
517   const ConversionSequence &rightToLeftConversionSequence() const {
518     return Data.ConversionRTL;
519   }
520 };
521 
522 // NOLINTNEXTLINE(misc-redundant-expression): Seems to be a bogus warning.
523 static_assert(std::is_trivially_copyable<Mix>::value &&
524                   std::is_trivially_move_constructible<Mix>::value &&
525                   std::is_trivially_move_assignable<Mix>::value,
526               "Keep frequently used data simple!");
527 
528 struct MixableParameterRange {
529   /// A container for Mixes.
530   using MixVector = SmallVector<Mix, 8>;
531 
532   /// The number of parameters iterated to build the instance.
533   std::size_t NumParamsChecked = 0;
534 
535   /// The individual flags and supporting information for the mixes.
536   MixVector Mixes;
537 
538   /// Gets the leftmost parameter of the range.
539   const ParmVarDecl *getFirstParam() const {
540     // The first element is the LHS of the very first mix in the range.
541     assert(!Mixes.empty());
542     return Mixes.front().First;
543   }
544 
545   /// Gets the rightmost parameter of the range.
546   const ParmVarDecl *getLastParam() const {
547     // The builder function breaks building an instance of this type if it
548     // finds something that can not be mixed with the rest, by going *forward*
549     // in the list of parameters. So at any moment of break, the RHS of the last
550     // element of the mix vector is also the last element of the mixing range.
551     assert(!Mixes.empty());
552     return Mixes.back().Second;
553   }
554 };
555 
556 /// Helper enum for the recursive calls in the modelling that toggle what kinds
557 /// of implicit conversions are to be modelled.
558 enum class ImplicitConversionModellingMode : unsigned char {
559   ///< No implicit conversions are modelled.
560   None,
561 
562   ///< The full implicit conversion sequence is modelled.
563   All,
564 
565   ///< Only model a unidirectional implicit conversion and within it only one
566   /// standard conversion sequence.
567   OneWaySingleStandardOnly
568 };
569 
570 static MixData
571 isLRefEquallyBindingToType(const TheCheck &Check,
572                            const LValueReferenceType *LRef, QualType Ty,
573                            const ASTContext &Ctx, bool IsRefRHS,
574                            ImplicitConversionModellingMode ImplicitMode);
575 
576 static MixData
577 approximateImplicitConversion(const TheCheck &Check, QualType LType,
578                               QualType RType, const ASTContext &Ctx,
579                               ImplicitConversionModellingMode ImplicitMode);
580 
581 static inline bool isUselessSugar(const Type *T) {
582   return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
583 }
584 
585 namespace {
586 
587 struct NonCVRQualifiersResult {
588   /// True if the types are qualified in a way that even after equating or
589   /// removing local CVR qualification, even if the unqualified types
590   /// themselves would mix, the qualified ones don't, because there are some
591   /// other local qualifiers that are not equal.
592   bool HasMixabilityBreakingQualifiers;
593 
594   /// The set of equal qualifiers between the two types.
595   Qualifiers CommonQualifiers;
596 };
597 
598 } // namespace
599 
600 /// Returns if the two types are qualified in a way that ever after equating or
601 /// removing local CVR qualification, even if the unqualified types would mix,
602 /// the qualified ones don't, because there are some other local qualifiers
603 /// that aren't equal.
604 static NonCVRQualifiersResult
605 getNonCVRQualifiers(const ASTContext &Ctx, QualType LType, QualType RType) {
606   LLVM_DEBUG(llvm::dbgs() << ">>> getNonCVRQualifiers for LType:\n";
607              LType.dump(llvm::dbgs(), Ctx); llvm::dbgs() << "\nand RType:\n";
608              RType.dump(llvm::dbgs(), Ctx); llvm::dbgs() << '\n';);
609   Qualifiers LQual = LType.getLocalQualifiers(),
610              RQual = RType.getLocalQualifiers();
611 
612   // Strip potential CVR. That is handled by the check option QualifiersMix.
613   LQual.removeCVRQualifiers();
614   RQual.removeCVRQualifiers();
615 
616   NonCVRQualifiersResult Ret;
617   Ret.CommonQualifiers = Qualifiers::removeCommonQualifiers(LQual, RQual);
618 
619   LLVM_DEBUG(llvm::dbgs() << "--- hasNonCVRMixabilityBreakingQualifiers. "
620                              "Removed common qualifiers: ";
621              Ret.CommonQualifiers.print(llvm::dbgs(), Ctx.getPrintingPolicy());
622              llvm::dbgs() << "\n\tremaining on LType: ";
623              LQual.print(llvm::dbgs(), Ctx.getPrintingPolicy());
624              llvm::dbgs() << "\n\tremaining on RType: ";
625              RQual.print(llvm::dbgs(), Ctx.getPrintingPolicy());
626              llvm::dbgs() << '\n';);
627 
628   // If there are no other non-cvr non-common qualifiers left, we can deduce
629   // that mixability isn't broken.
630   Ret.HasMixabilityBreakingQualifiers =
631       LQual.hasQualifiers() || RQual.hasQualifiers();
632 
633   return Ret;
634 }
635 
636 /// Approximate the way how LType and RType might refer to "essentially the
637 /// same" type, in a sense that at a particular call site, an expression of
638 /// type LType and RType might be successfully passed to a variable (in our
639 /// specific case, a parameter) of type RType and LType, respectively.
640 /// Note the swapped order!
641 ///
642 /// The returned data structure is not guaranteed to be properly set, as this
643 /// function is potentially recursive. It is the caller's responsibility to
644 /// call sanitize() on the result once the recursion is over.
645 static MixData
646 calculateMixability(const TheCheck &Check, QualType LType, QualType RType,
647                     const ASTContext &Ctx,
648                     ImplicitConversionModellingMode ImplicitMode) {
649   LLVM_DEBUG(llvm::dbgs() << ">>> calculateMixability for LType:\n";
650              LType.dump(llvm::dbgs(), Ctx); llvm::dbgs() << "\nand RType:\n";
651              RType.dump(llvm::dbgs(), Ctx); llvm::dbgs() << '\n';);
652   if (LType == RType) {
653     LLVM_DEBUG(llvm::dbgs() << "<<< calculateMixability. Trivial equality.\n");
654     return {MixFlags::Trivial, LType};
655   }
656 
657   // Dissolve certain type sugars that do not affect the mixability of one type
658   // with the other, and also do not require any sort of elaboration for the
659   // user to understand.
660   if (isUselessSugar(LType.getTypePtr())) {
661     LLVM_DEBUG(llvm::dbgs()
662                << "--- calculateMixability. LHS is useless sugar.\n");
663     return calculateMixability(Check, LType.getSingleStepDesugaredType(Ctx),
664                                RType, Ctx, ImplicitMode);
665   }
666   if (isUselessSugar(RType.getTypePtr())) {
667     LLVM_DEBUG(llvm::dbgs()
668                << "--- calculateMixability. RHS is useless sugar.\n");
669     return calculateMixability(
670         Check, LType, RType.getSingleStepDesugaredType(Ctx), Ctx, ImplicitMode);
671   }
672 
673   const auto *LLRef = LType->getAs<LValueReferenceType>();
674   const auto *RLRef = RType->getAs<LValueReferenceType>();
675   if (LLRef && RLRef) {
676     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. LHS and RHS are &.\n");
677 
678     return calculateMixability(Check, LLRef->getPointeeType(),
679                                RLRef->getPointeeType(), Ctx, ImplicitMode)
680         .withCommonTypeTransformed(
681             [&Ctx](QualType QT) { return Ctx.getLValueReferenceType(QT); });
682   }
683   // At a particular call site, what could be passed to a 'T' or 'const T' might
684   // also be passed to a 'const T &' without the call site putting a direct
685   // side effect on the passed expressions.
686   if (LLRef) {
687     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. LHS is &.\n");
688     return isLRefEquallyBindingToType(Check, LLRef, RType, Ctx, false,
689                                       ImplicitMode) |
690            MixFlags::ReferenceBind;
691   }
692   if (RLRef) {
693     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. RHS is &.\n");
694     return isLRefEquallyBindingToType(Check, RLRef, LType, Ctx, true,
695                                       ImplicitMode) |
696            MixFlags::ReferenceBind;
697   }
698 
699   if (LType->getAs<TypedefType>()) {
700     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. LHS is typedef.\n");
701     return calculateMixability(Check, LType.getSingleStepDesugaredType(Ctx),
702                                RType, Ctx, ImplicitMode) |
703            MixFlags::TypeAlias;
704   }
705   if (RType->getAs<TypedefType>()) {
706     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. RHS is typedef.\n");
707     return calculateMixability(Check, LType,
708                                RType.getSingleStepDesugaredType(Ctx), Ctx,
709                                ImplicitMode) |
710            MixFlags::TypeAlias;
711   }
712 
713   // A parameter of type 'cvr1 T' and another of potentially differently
714   // qualified 'cvr2 T' may bind with the same power, if the user so requested.
715   //
716   // Whether to do this check for the inner unqualified types.
717   bool CompareUnqualifiedTypes = false;
718   if (LType.getLocalCVRQualifiers() != RType.getLocalCVRQualifiers()) {
719     LLVM_DEBUG(if (LType.getLocalCVRQualifiers()) {
720       llvm::dbgs() << "--- calculateMixability. LHS has CVR-Qualifiers: ";
721       Qualifiers::fromCVRMask(LType.getLocalCVRQualifiers())
722           .print(llvm::dbgs(), Ctx.getPrintingPolicy());
723       llvm::dbgs() << '\n';
724     });
725     LLVM_DEBUG(if (RType.getLocalCVRQualifiers()) {
726       llvm::dbgs() << "--- calculateMixability. RHS has CVR-Qualifiers: ";
727       Qualifiers::fromCVRMask(RType.getLocalCVRQualifiers())
728           .print(llvm::dbgs(), Ctx.getPrintingPolicy());
729       llvm::dbgs() << '\n';
730     });
731 
732     if (!Check.QualifiersMix) {
733       LLVM_DEBUG(llvm::dbgs()
734                  << "<<< calculateMixability. QualifiersMix turned off - not "
735                     "mixable.\n");
736       return {MixFlags::None};
737     }
738 
739     CompareUnqualifiedTypes = true;
740   }
741   // Whether the two types had the same CVR qualifiers.
742   bool OriginallySameQualifiers = false;
743   if (LType.getLocalCVRQualifiers() == RType.getLocalCVRQualifiers() &&
744       LType.getLocalCVRQualifiers() != 0) {
745     LLVM_DEBUG(if (LType.getLocalCVRQualifiers()) {
746       llvm::dbgs()
747           << "--- calculateMixability. LHS and RHS have same CVR-Qualifiers: ";
748       Qualifiers::fromCVRMask(LType.getLocalCVRQualifiers())
749           .print(llvm::dbgs(), Ctx.getPrintingPolicy());
750       llvm::dbgs() << '\n';
751     });
752 
753     CompareUnqualifiedTypes = true;
754     OriginallySameQualifiers = true;
755   }
756 
757   if (CompareUnqualifiedTypes) {
758     NonCVRQualifiersResult AdditionalQuals =
759         getNonCVRQualifiers(Ctx, LType, RType);
760     if (AdditionalQuals.HasMixabilityBreakingQualifiers) {
761       LLVM_DEBUG(llvm::dbgs() << "<<< calculateMixability. Additional "
762                                  "non-equal incompatible qualifiers.\n");
763       return {MixFlags::None};
764     }
765 
766     MixData UnqualifiedMixability =
767         calculateMixability(Check, LType.getLocalUnqualifiedType(),
768                             RType.getLocalUnqualifiedType(), Ctx, ImplicitMode)
769             .withCommonTypeTransformed([&AdditionalQuals, &Ctx](QualType QT) {
770               // Once the mixability was deduced, apply the qualifiers common
771               // to the two type back onto the diagnostic printout.
772               return Ctx.getQualifiedType(QT, AdditionalQuals.CommonQualifiers);
773             });
774 
775     if (!OriginallySameQualifiers)
776       // User-enabled qualifier change modelled for the mix.
777       return UnqualifiedMixability | MixFlags::Qualifiers;
778 
779     // Apply the same qualifier back into the found common type if they were
780     // the same.
781     return UnqualifiedMixability.withCommonTypeTransformed(
782         [&Ctx, LType](QualType QT) {
783           return Ctx.getQualifiedType(QT, LType.getLocalQualifiers());
784         });
785   }
786 
787   // Certain constructs match on the last catch-all getCanonicalType() equality,
788   // which is perhaps something not what we want. If this variable is true,
789   // the canonical type equality will be ignored.
790   bool RecursiveReturnDiscardingCanonicalType = false;
791 
792   if (LType->isPointerType() && RType->isPointerType()) {
793     // If both types are pointers, and pointed to the exact same type,
794     // LType == RType took care of that. Try to see if the pointee type has
795     // some other match. However, this must not consider implicit conversions.
796     LLVM_DEBUG(llvm::dbgs()
797                << "--- calculateMixability. LHS and RHS are Ptrs.\n");
798     MixData MixOfPointee =
799         calculateMixability(Check, LType->getPointeeType(),
800                             RType->getPointeeType(), Ctx,
801                             ImplicitConversionModellingMode::None)
802             .withCommonTypeTransformed(
803                 [&Ctx](QualType QT) { return Ctx.getPointerType(QT); });
804     if (hasFlag(MixOfPointee.Flags,
805                 MixFlags::WorkaroundDisableCanonicalEquivalence))
806       RecursiveReturnDiscardingCanonicalType = true;
807 
808     MixOfPointee.sanitize();
809     if (MixOfPointee.indicatesMixability()) {
810       LLVM_DEBUG(llvm::dbgs()
811                  << "<<< calculateMixability. Pointees are mixable.\n");
812       return MixOfPointee;
813     }
814   }
815 
816   if (ImplicitMode > ImplicitConversionModellingMode::None) {
817     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. Start implicit...\n");
818     MixData MixLTR =
819         approximateImplicitConversion(Check, LType, RType, Ctx, ImplicitMode);
820     LLVM_DEBUG(
821         if (hasFlag(MixLTR.Flags, MixFlags::ImplicitConversion)) llvm::dbgs()
822             << "--- calculateMixability. Implicit Left -> Right found.\n";);
823 
824     if (ImplicitMode ==
825             ImplicitConversionModellingMode::OneWaySingleStandardOnly &&
826         MixLTR.Conversion && !MixLTR.Conversion.AfterFirstStandard.isNull() &&
827         MixLTR.Conversion.UDConvKind == ConversionSequence::UDCK_None &&
828         MixLTR.Conversion.AfterSecondStandard.isNull()) {
829       // The invoker of the method requested only modelling a single standard
830       // conversion, in only the forward direction, and they got just that.
831       LLVM_DEBUG(llvm::dbgs() << "<<< calculateMixability. Implicit "
832                                  "conversion, one-way, standard-only.\n");
833       return {MixFlags::ImplicitConversion, MixLTR.Conversion};
834     }
835 
836     // Otherwise if the invoker requested a full modelling, do the other
837     // direction as well.
838     MixData MixRTL =
839         approximateImplicitConversion(Check, RType, LType, Ctx, ImplicitMode);
840     LLVM_DEBUG(
841         if (hasFlag(MixRTL.Flags, MixFlags::ImplicitConversion)) llvm::dbgs()
842             << "--- calculateMixability. Implicit Right -> Left found.\n";);
843 
844     if (MixLTR.Conversion && MixRTL.Conversion) {
845       LLVM_DEBUG(
846           llvm::dbgs()
847           << "<<< calculateMixability. Implicit conversion, bidirectional.\n");
848       return {MixFlags::ImplicitConversion, MixLTR.Conversion,
849               MixRTL.Conversion};
850     }
851   }
852 
853   if (RecursiveReturnDiscardingCanonicalType)
854     LLVM_DEBUG(llvm::dbgs() << "--- calculateMixability. Before CanonicalType, "
855                                "Discard was enabled.\n");
856 
857   // Certain kinds unfortunately need to be side-stepped for canonical type
858   // matching.
859   if (LType->getAs<FunctionProtoType>() || RType->getAs<FunctionProtoType>()) {
860     // Unfortunately, the canonical type of a function pointer becomes the
861     // same even if exactly one is "noexcept" and the other isn't, making us
862     // give a false positive report irrespective of implicit conversions.
863     LLVM_DEBUG(llvm::dbgs()
864                << "--- calculateMixability. Discarding potential canonical "
865                   "equivalence on FunctionProtoTypes.\n");
866     RecursiveReturnDiscardingCanonicalType = true;
867   }
868 
869   MixData MixToReturn{MixFlags::None};
870 
871   // If none of the previous logic found a match, try if Clang otherwise
872   // believes the types to be the same.
873   QualType LCanonical = LType.getCanonicalType();
874   if (LCanonical == RType.getCanonicalType()) {
875     LLVM_DEBUG(llvm::dbgs()
876                << "<<< calculateMixability. Same CanonicalType.\n");
877     MixToReturn = {MixFlags::Canonical, LCanonical};
878   }
879 
880   if (RecursiveReturnDiscardingCanonicalType)
881     MixToReturn |= MixFlags::WorkaroundDisableCanonicalEquivalence;
882 
883   LLVM_DEBUG(if (MixToReturn.Flags == MixFlags::None) llvm::dbgs()
884              << "<<< calculateMixability. No match found.\n");
885   return MixToReturn;
886 }
887 
888 /// Calculates if the reference binds an expression of the given type. This is
889 /// true iff 'LRef' is some 'const T &' type, and the 'Ty' is 'T' or 'const T'.
890 ///
891 /// \param ImplicitMode is forwarded in the possible recursive call to
892 /// calculateMixability.
893 static MixData
894 isLRefEquallyBindingToType(const TheCheck &Check,
895                            const LValueReferenceType *LRef, QualType Ty,
896                            const ASTContext &Ctx, bool IsRefRHS,
897                            ImplicitConversionModellingMode ImplicitMode) {
898   LLVM_DEBUG(llvm::dbgs() << ">>> isLRefEquallyBindingToType for LRef:\n";
899              LRef->dump(llvm::dbgs(), Ctx); llvm::dbgs() << "\nand Type:\n";
900              Ty.dump(llvm::dbgs(), Ctx); llvm::dbgs() << '\n';);
901 
902   QualType ReferredType = LRef->getPointeeType();
903   if (!ReferredType.isLocalConstQualified() &&
904       ReferredType->getAs<TypedefType>()) {
905     LLVM_DEBUG(
906         llvm::dbgs()
907         << "--- isLRefEquallyBindingToType. Non-const LRef to Typedef.\n");
908     ReferredType = ReferredType.getDesugaredType(Ctx);
909     if (!ReferredType.isLocalConstQualified()) {
910       LLVM_DEBUG(llvm::dbgs()
911                  << "<<< isLRefEquallyBindingToType. Typedef is not const.\n");
912       return {MixFlags::None};
913     }
914 
915     LLVM_DEBUG(llvm::dbgs() << "--- isLRefEquallyBindingToType. Typedef is "
916                                "const, considering as const LRef.\n");
917   } else if (!ReferredType.isLocalConstQualified()) {
918     LLVM_DEBUG(llvm::dbgs()
919                << "<<< isLRefEquallyBindingToType. Not const LRef.\n");
920     return {MixFlags::None};
921   };
922 
923   assert(ReferredType.isLocalConstQualified() &&
924          "Reaching this point means we are sure LRef is effectively a const&.");
925 
926   if (ReferredType == Ty) {
927     LLVM_DEBUG(
928         llvm::dbgs()
929         << "<<< isLRefEquallyBindingToType. Type of referred matches.\n");
930     return {MixFlags::Trivial, ReferredType};
931   }
932 
933   QualType NonConstReferredType = ReferredType;
934   NonConstReferredType.removeLocalConst();
935   if (NonConstReferredType == Ty) {
936     LLVM_DEBUG(llvm::dbgs() << "<<< isLRefEquallyBindingToType. Type of "
937                                "referred matches to non-const qualified.\n");
938     return {MixFlags::Trivial, NonConstReferredType};
939   }
940 
941   LLVM_DEBUG(
942       llvm::dbgs()
943       << "--- isLRefEquallyBindingToType. Checking mix for underlying type.\n");
944   return IsRefRHS ? calculateMixability(Check, Ty, NonConstReferredType, Ctx,
945                                         ImplicitMode)
946                   : calculateMixability(Check, NonConstReferredType, Ty, Ctx,
947                                         ImplicitMode);
948 }
949 
950 static inline bool isDerivedToBase(const CXXRecordDecl *Derived,
951                                    const CXXRecordDecl *Base) {
952   return Derived && Base && Derived->isCompleteDefinition() &&
953          Base->isCompleteDefinition() && Derived->isDerivedFrom(Base);
954 }
955 
956 static std::optional<QualType>
957 approximateStandardConversionSequence(const TheCheck &Check, QualType From,
958                                       QualType To, const ASTContext &Ctx) {
959   LLVM_DEBUG(llvm::dbgs() << ">>> approximateStdConv for LType:\n";
960              From.dump(llvm::dbgs(), Ctx); llvm::dbgs() << "\nand RType:\n";
961              To.dump(llvm::dbgs(), Ctx); llvm::dbgs() << '\n';);
962 
963   // A standard conversion sequence consists of the following, in order:
964   //  * Maybe either LValue->RValue conv., Array->Ptr conv., Function->Ptr conv.
965   //  * Maybe Numeric promotion or conversion.
966   //  * Maybe function pointer conversion.
967   //  * Maybe qualifier adjustments.
968   QualType WorkType = From;
969   // Get out the qualifiers of the original type. This will always be
970   // re-applied to the WorkType to ensure it is the same qualification as the
971   // original From was.
972   auto QualifiersToApply = From.split().Quals.getAsOpaqueValue();
973 
974   // LValue->RValue is irrelevant for the check, because it is a thing to be
975   // done at a call site, and will be performed if need be performed.
976 
977   // Array->Pointer decay is handled by the main method in desugaring
978   // the parameter's DecayedType as "useless sugar".
979 
980   // Function->Pointer conversions are also irrelevant, because a
981   // "FunctionType" cannot be the type of a parameter variable, so this
982   // conversion is only meaningful at call sites.
983 
984   // Numeric promotions and conversions.
985   const auto *FromBuiltin = WorkType->getAs<BuiltinType>();
986   const auto *ToBuiltin = To->getAs<BuiltinType>();
987   bool FromNumeric = FromBuiltin && (FromBuiltin->isIntegerType() ||
988                                      FromBuiltin->isFloatingType());
989   bool ToNumeric =
990       ToBuiltin && (ToBuiltin->isIntegerType() || ToBuiltin->isFloatingType());
991   if (FromNumeric && ToNumeric) {
992     // If both are integral types, the numeric conversion is performed.
993     // Reapply the qualifiers of the original type, however, so
994     // "const int -> double" in this case moves over to
995     // "const double -> double".
996     LLVM_DEBUG(llvm::dbgs()
997                << "--- approximateStdConv. Conversion between numerics.\n");
998     WorkType = QualType{ToBuiltin, QualifiersToApply};
999   }
1000 
1001   const auto *FromEnum = WorkType->getAs<EnumType>();
1002   const auto *ToEnum = To->getAs<EnumType>();
1003   if (FromEnum && ToNumeric && FromEnum->isUnscopedEnumerationType()) {
1004     // Unscoped enumerations (or enumerations in C) convert to numerics.
1005     LLVM_DEBUG(llvm::dbgs()
1006                << "--- approximateStdConv. Unscoped enum to numeric.\n");
1007     WorkType = QualType{ToBuiltin, QualifiersToApply};
1008   } else if (FromNumeric && ToEnum && ToEnum->isUnscopedEnumerationType()) {
1009     // Numeric types convert to enumerations only in C.
1010     if (Ctx.getLangOpts().CPlusPlus) {
1011       LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Numeric to unscoped "
1012                                  "enum, not possible in C++!\n");
1013       return {};
1014     }
1015 
1016     LLVM_DEBUG(llvm::dbgs()
1017                << "--- approximateStdConv. Numeric to unscoped enum.\n");
1018     WorkType = QualType{ToEnum, QualifiersToApply};
1019   }
1020 
1021   // Check for pointer conversions.
1022   const auto *FromPtr = WorkType->getAs<PointerType>();
1023   const auto *ToPtr = To->getAs<PointerType>();
1024   if (FromPtr && ToPtr) {
1025     if (ToPtr->isVoidPointerType()) {
1026       LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. To void pointer.\n");
1027       WorkType = QualType{ToPtr, QualifiersToApply};
1028     }
1029 
1030     const auto *FromRecordPtr = FromPtr->getPointeeCXXRecordDecl();
1031     const auto *ToRecordPtr = ToPtr->getPointeeCXXRecordDecl();
1032     if (isDerivedToBase(FromRecordPtr, ToRecordPtr)) {
1033       LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived* to Base*\n");
1034       WorkType = QualType{ToPtr, QualifiersToApply};
1035     }
1036   }
1037 
1038   // Model the slicing Derived-to-Base too, as "BaseT temporary = derived;"
1039   // can also be compiled.
1040   const auto *FromRecord = WorkType->getAsCXXRecordDecl();
1041   const auto *ToRecord = To->getAsCXXRecordDecl();
1042   if (isDerivedToBase(FromRecord, ToRecord)) {
1043     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
1044     WorkType = QualType{ToRecord->getTypeForDecl(), QualifiersToApply};
1045   }
1046 
1047   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
1048     // Function pointer conversion: A noexcept function pointer can be passed
1049     // to a non-noexcept one.
1050     const auto *FromFunctionPtr =
1051         FromPtr->getPointeeType()->getAs<FunctionProtoType>();
1052     const auto *ToFunctionPtr =
1053         ToPtr->getPointeeType()->getAs<FunctionProtoType>();
1054     if (FromFunctionPtr && ToFunctionPtr &&
1055         FromFunctionPtr->hasNoexceptExceptionSpec() &&
1056         !ToFunctionPtr->hasNoexceptExceptionSpec()) {
1057       LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. noexcept function "
1058                                  "pointer to non-noexcept.\n");
1059       WorkType = QualType{ToPtr, QualifiersToApply};
1060     }
1061   }
1062 
1063   // Qualifier adjustments are modelled according to the user's request in
1064   // the QualifiersMix check config.
1065   LLVM_DEBUG(llvm::dbgs()
1066              << "--- approximateStdConv. Trying qualifier adjustment...\n");
1067   MixData QualConv = calculateMixability(Check, WorkType, To, Ctx,
1068                                          ImplicitConversionModellingMode::None);
1069   QualConv.sanitize();
1070   if (hasFlag(QualConv.Flags, MixFlags::Qualifiers)) {
1071     LLVM_DEBUG(llvm::dbgs()
1072                << "<<< approximateStdConv. Qualifiers adjusted.\n");
1073     WorkType = To;
1074   }
1075 
1076   if (WorkType == To) {
1077     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
1078     return {WorkType};
1079   }
1080 
1081   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
1082   return {};
1083 }
1084 
1085 namespace {
1086 
1087 /// Helper class for storing possible user-defined conversion calls that
1088 /// *could* take place in an implicit conversion, and selecting the one that
1089 /// most likely *does*, if any.
1090 class UserDefinedConversionSelector {
1091 public:
1092   /// The conversion associated with a conversion function, together with the
1093   /// mixability flags of the conversion function's parameter or return type
1094   /// to the rest of the sequence the selector is used in, and the sequence
1095   /// that applied through the conversion itself.
1096   struct PreparedConversion {
1097     const CXXMethodDecl *ConversionFun;
1098     MixFlags Flags;
1099     ConversionSequence Seq;
1100 
1101     PreparedConversion(const CXXMethodDecl *CMD, MixFlags F,
1102                        ConversionSequence S)
1103         : ConversionFun(CMD), Flags(F), Seq(S) {}
1104   };
1105 
1106   UserDefinedConversionSelector(const TheCheck &Check) : Check(Check) {}
1107 
1108   /// Adds the conversion between the two types for the given function into
1109   /// the possible implicit conversion set. FromType and ToType is either:
1110   ///   * the result of a standard sequence and a converting ctor parameter
1111   ///   * the return type of a conversion operator and the expected target of
1112   ///     an implicit conversion.
1113   void addConversion(const CXXMethodDecl *ConvFun, QualType FromType,
1114                      QualType ToType) {
1115     // Try to go from the FromType to the ToType with only a single implicit
1116     // conversion, to see if the conversion function is applicable.
1117     MixData Mix = calculateMixability(
1118         Check, FromType, ToType, ConvFun->getASTContext(),
1119         ImplicitConversionModellingMode::OneWaySingleStandardOnly);
1120     Mix.sanitize();
1121     if (!Mix.indicatesMixability())
1122       return;
1123 
1124     LLVM_DEBUG(llvm::dbgs() << "--- tryConversion. Found viable with flags: "
1125                             << formatMixFlags(Mix.Flags) << '\n');
1126     FlaggedConversions.emplace_back(ConvFun, Mix.Flags, Mix.Conversion);
1127   }
1128 
1129   /// Selects the best conversion function that is applicable from the
1130   /// prepared set of potential conversion functions taken.
1131   std::optional<PreparedConversion> operator()() const {
1132     if (FlaggedConversions.empty()) {
1133       LLVM_DEBUG(llvm::dbgs() << "--- selectUserDefinedConv. Empty.\n");
1134       return {};
1135     }
1136     if (FlaggedConversions.size() == 1) {
1137       LLVM_DEBUG(llvm::dbgs() << "--- selectUserDefinedConv. Single.\n");
1138       return FlaggedConversions.front();
1139     }
1140 
1141     std::optional<PreparedConversion> BestConversion;
1142     unsigned short HowManyGoodConversions = 0;
1143     for (const auto &Prepared : FlaggedConversions) {
1144       LLVM_DEBUG(llvm::dbgs() << "--- selectUserDefinedConv. Candidate flags: "
1145                               << formatMixFlags(Prepared.Flags) << '\n');
1146       if (!BestConversion) {
1147         BestConversion = Prepared;
1148         ++HowManyGoodConversions;
1149         continue;
1150       }
1151 
1152       bool BestConversionHasImplicit =
1153           hasFlag(BestConversion->Flags, MixFlags::ImplicitConversion);
1154       bool ThisConversionHasImplicit =
1155           hasFlag(Prepared.Flags, MixFlags::ImplicitConversion);
1156       if (!BestConversionHasImplicit && ThisConversionHasImplicit)
1157         // This is a worse conversion, because a better one was found earlier.
1158         continue;
1159 
1160       if (BestConversionHasImplicit && !ThisConversionHasImplicit) {
1161         // If the so far best selected conversion needs a previous implicit
1162         // conversion to match the user-defined converting function, but this
1163         // conversion does not, this is a better conversion, and we can throw
1164         // away the previously selected conversion(s).
1165         BestConversion = Prepared;
1166         HowManyGoodConversions = 1;
1167         continue;
1168       }
1169 
1170       if (BestConversionHasImplicit == ThisConversionHasImplicit)
1171         // The current conversion is the same in term of goodness than the
1172         // already selected one.
1173         ++HowManyGoodConversions;
1174     }
1175 
1176     if (HowManyGoodConversions == 1) {
1177       LLVM_DEBUG(llvm::dbgs()
1178                  << "--- selectUserDefinedConv. Unique result. Flags: "
1179                  << formatMixFlags(BestConversion->Flags) << '\n');
1180       return BestConversion;
1181     }
1182 
1183     LLVM_DEBUG(llvm::dbgs()
1184                << "--- selectUserDefinedConv. No, or ambiguous.\n");
1185     return {};
1186   }
1187 
1188 private:
1189   llvm::SmallVector<PreparedConversion, 2> FlaggedConversions;
1190   const TheCheck &Check;
1191 };
1192 
1193 } // namespace
1194 
1195 static std::optional<ConversionSequence>
1196 tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
1197                        QualType ToType) {
1198   if (!RD || !RD->isCompleteDefinition())
1199     return {};
1200   RD = RD->getDefinition();
1201 
1202   LLVM_DEBUG(llvm::dbgs() << ">>> tryConversionOperators: " << RD->getName()
1203                           << " to:\n";
1204              ToType.dump(llvm::dbgs(), RD->getASTContext());
1205              llvm::dbgs() << '\n';);
1206 
1207   UserDefinedConversionSelector ConversionSet{Check};
1208 
1209   for (const NamedDecl *Method : RD->getVisibleConversionFunctions()) {
1210     const auto *Con = dyn_cast<CXXConversionDecl>(Method);
1211     if (!Con || Con->isExplicit())
1212       continue;
1213     LLVM_DEBUG(llvm::dbgs() << "--- tryConversionOperators. Trying:\n";
1214                Con->dump(llvm::dbgs()); llvm::dbgs() << '\n';);
1215 
1216     // Try to go from the result of conversion operator to the expected type,
1217     // without calculating another user-defined conversion.
1218     ConversionSet.addConversion(Con, Con->getConversionType(), ToType);
1219   }
1220 
1221   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
1222           SelectedConversion = ConversionSet()) {
1223     QualType RecordType{RD->getTypeForDecl(), 0};
1224 
1225     ConversionSequence Result{RecordType, ToType};
1226     // The conversion from the operator call's return type to ToType was
1227     // modelled as a "pre-conversion" in the operator call, but it is the
1228     // "post-conversion" from the point of view of the original conversion
1229     // we are modelling.
1230     Result.AfterSecondStandard = SelectedConversion->Seq.AfterFirstStandard;
1231 
1232     ConversionSequence::UserDefinedConversionOperator ConvOp;
1233     ConvOp.Fun = cast<CXXConversionDecl>(SelectedConversion->ConversionFun);
1234     ConvOp.UserDefinedType = RecordType;
1235     ConvOp.ConversionOperatorResultType = ConvOp.Fun->getConversionType();
1236     Result.setConversion(ConvOp);
1237 
1238     LLVM_DEBUG(llvm::dbgs() << "<<< tryConversionOperators. Found result.\n");
1239     return Result;
1240   }
1241 
1242   LLVM_DEBUG(llvm::dbgs() << "<<< tryConversionOperators. No conversion.\n");
1243   return {};
1244 }
1245 
1246 static std::optional<ConversionSequence>
1247 tryConvertingConstructors(const TheCheck &Check, QualType FromType,
1248                           const CXXRecordDecl *RD) {
1249   if (!RD || !RD->isCompleteDefinition())
1250     return {};
1251   RD = RD->getDefinition();
1252 
1253   LLVM_DEBUG(llvm::dbgs() << ">>> tryConveringConstructors: " << RD->getName()
1254                           << " from:\n";
1255              FromType.dump(llvm::dbgs(), RD->getASTContext());
1256              llvm::dbgs() << '\n';);
1257 
1258   UserDefinedConversionSelector ConversionSet{Check};
1259 
1260   for (const CXXConstructorDecl *Con : RD->ctors()) {
1261     if (Con->isCopyOrMoveConstructor() ||
1262         !Con->isConvertingConstructor(/* AllowExplicit =*/false))
1263       continue;
1264     LLVM_DEBUG(llvm::dbgs() << "--- tryConvertingConstructors. Trying:\n";
1265                Con->dump(llvm::dbgs()); llvm::dbgs() << '\n';);
1266 
1267     // Try to go from the original FromType to the converting constructor's
1268     // parameter type without another user-defined conversion.
1269     ConversionSet.addConversion(Con, FromType, Con->getParamDecl(0)->getType());
1270   }
1271 
1272   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
1273           SelectedConversion = ConversionSet()) {
1274     QualType RecordType{RD->getTypeForDecl(), 0};
1275 
1276     ConversionSequence Result{FromType, RecordType};
1277     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
1278 
1279     ConversionSequence::UserDefinedConvertingConstructor Ctor;
1280     Ctor.Fun = cast<CXXConstructorDecl>(SelectedConversion->ConversionFun);
1281     Ctor.ConstructorParameterType = Ctor.Fun->getParamDecl(0)->getType();
1282     Ctor.UserDefinedType = RecordType;
1283     Result.setConversion(Ctor);
1284 
1285     LLVM_DEBUG(llvm::dbgs()
1286                << "<<< tryConvertingConstructors. Found result.\n");
1287     return Result;
1288   }
1289 
1290   LLVM_DEBUG(llvm::dbgs() << "<<< tryConvertingConstructors. No conversion.\n");
1291   return {};
1292 }
1293 
1294 /// Returns whether an expression of LType can be used in an RType context, as
1295 /// per the implicit conversion rules.
1296 ///
1297 /// Note: the result of this operation, unlike that of calculateMixability, is
1298 /// **NOT** symmetric.
1299 static MixData
1300 approximateImplicitConversion(const TheCheck &Check, QualType LType,
1301                               QualType RType, const ASTContext &Ctx,
1302                               ImplicitConversionModellingMode ImplicitMode) {
1303   LLVM_DEBUG(llvm::dbgs() << ">>> approximateImplicitConversion for LType:\n";
1304              LType.dump(llvm::dbgs(), Ctx); llvm::dbgs() << "\nand RType:\n";
1305              RType.dump(llvm::dbgs(), Ctx);
1306              llvm::dbgs() << "\nimplicit mode: "; switch (ImplicitMode) {
1307                case ImplicitConversionModellingMode::None:
1308                  llvm::dbgs() << "None";
1309                  break;
1310                case ImplicitConversionModellingMode::All:
1311                  llvm::dbgs() << "All";
1312                  break;
1313                case ImplicitConversionModellingMode::OneWaySingleStandardOnly:
1314                  llvm::dbgs() << "OneWay, Single, STD Only";
1315                  break;
1316              } llvm::dbgs() << '\n';);
1317   if (LType == RType)
1318     return {MixFlags::Trivial, LType};
1319 
1320   // An implicit conversion sequence consists of the following, in order:
1321   //  * Maybe standard conversion sequence.
1322   //  * Maybe user-defined conversion.
1323   //  * Maybe standard conversion sequence.
1324   ConversionSequence ImplicitSeq{LType, RType};
1325   QualType WorkType = LType;
1326 
1327   std::optional<QualType> AfterFirstStdConv =
1328       approximateStandardConversionSequence(Check, LType, RType, Ctx);
1329   if (AfterFirstStdConv) {
1330     LLVM_DEBUG(llvm::dbgs() << "--- approximateImplicitConversion. Standard "
1331                                "Pre-Conversion found!\n");
1332     ImplicitSeq.AfterFirstStandard = *AfterFirstStdConv;
1333     WorkType = ImplicitSeq.AfterFirstStandard;
1334   }
1335 
1336   if (ImplicitMode == ImplicitConversionModellingMode::OneWaySingleStandardOnly)
1337     // If the caller only requested modelling of a standard conversion, bail.
1338     return {ImplicitSeq.AfterFirstStandard.isNull()
1339                 ? MixFlags::None
1340                 : MixFlags::ImplicitConversion,
1341             ImplicitSeq};
1342 
1343   if (Ctx.getLangOpts().CPlusPlus) {
1344     bool FoundConversionOperator = false, FoundConvertingCtor = false;
1345 
1346     if (const auto *LRD = WorkType->getAsCXXRecordDecl()) {
1347       std::optional<ConversionSequence> ConversionOperatorResult =
1348           tryConversionOperators(Check, LRD, RType);
1349       if (ConversionOperatorResult) {
1350         LLVM_DEBUG(llvm::dbgs() << "--- approximateImplicitConversion. Found "
1351                                    "conversion operator.\n");
1352         ImplicitSeq.update(*ConversionOperatorResult);
1353         WorkType = ImplicitSeq.getTypeAfterUserDefinedConversion();
1354         FoundConversionOperator = true;
1355       }
1356     }
1357 
1358     if (const auto *RRD = RType->getAsCXXRecordDecl()) {
1359       // Use the original "LType" here, and not WorkType, because the
1360       // conversion to the converting constructors' parameters will be
1361       // modelled in the recursive call.
1362       std::optional<ConversionSequence> ConvCtorResult =
1363           tryConvertingConstructors(Check, LType, RRD);
1364       if (ConvCtorResult) {
1365         LLVM_DEBUG(llvm::dbgs() << "--- approximateImplicitConversion. Found "
1366                                    "converting constructor.\n");
1367         ImplicitSeq.update(*ConvCtorResult);
1368         WorkType = ImplicitSeq.getTypeAfterUserDefinedConversion();
1369         FoundConvertingCtor = true;
1370       }
1371     }
1372 
1373     if (FoundConversionOperator && FoundConvertingCtor) {
1374       // If both an operator and a ctor matches, the sequence is ambiguous.
1375       LLVM_DEBUG(llvm::dbgs()
1376                  << "<<< approximateImplicitConversion. Found both "
1377                     "user-defined conversion kinds in the same sequence!\n");
1378       return {MixFlags::None};
1379     }
1380   }
1381 
1382   // After the potential user-defined conversion, another standard conversion
1383   // sequence might exist.
1384   LLVM_DEBUG(
1385       llvm::dbgs()
1386       << "--- approximateImplicitConversion. Try to find post-conversion.\n");
1387   MixData SecondStdConv = approximateImplicitConversion(
1388       Check, WorkType, RType, Ctx,
1389       ImplicitConversionModellingMode::OneWaySingleStandardOnly);
1390   if (SecondStdConv.indicatesMixability()) {
1391     LLVM_DEBUG(llvm::dbgs() << "--- approximateImplicitConversion. Standard "
1392                                "Post-Conversion found!\n");
1393 
1394     // The single-step modelling puts the modelled conversion into the "PreStd"
1395     // variable in the recursive call, but from the PoV of this function, it is
1396     // the post-conversion.
1397     ImplicitSeq.AfterSecondStandard =
1398         SecondStdConv.Conversion.AfterFirstStandard;
1399     WorkType = ImplicitSeq.AfterSecondStandard;
1400   }
1401 
1402   if (ImplicitSeq) {
1403     LLVM_DEBUG(llvm::dbgs()
1404                << "<<< approximateImplicitConversion. Found a conversion.\n");
1405     return {MixFlags::ImplicitConversion, ImplicitSeq};
1406   }
1407 
1408   LLVM_DEBUG(
1409       llvm::dbgs() << "<<< approximateImplicitConversion. No match found.\n");
1410   return {MixFlags::None};
1411 }
1412 
1413 static MixableParameterRange modelMixingRange(
1414     const TheCheck &Check, const FunctionDecl *FD, std::size_t StartIndex,
1415     const filter::SimilarlyUsedParameterPairSuppressor &UsageBasedSuppressor) {
1416   std::size_t NumParams = FD->getNumParams();
1417   assert(StartIndex < NumParams && "out of bounds for start");
1418   const ASTContext &Ctx = FD->getASTContext();
1419 
1420   MixableParameterRange Ret;
1421   // A parameter at index 'StartIndex' had been trivially "checked".
1422   Ret.NumParamsChecked = 1;
1423 
1424   for (std::size_t I = StartIndex + 1; I < NumParams; ++I) {
1425     const ParmVarDecl *Ith = FD->getParamDecl(I);
1426     StringRef ParamName = Ith->getName();
1427     LLVM_DEBUG(llvm::dbgs()
1428                << "Check param #" << I << " '" << ParamName << "'...\n");
1429     if (filter::isIgnoredParameter(Check, Ith)) {
1430       LLVM_DEBUG(llvm::dbgs() << "Param #" << I << " is ignored. Break!\n");
1431       break;
1432     }
1433 
1434     StringRef PrevParamName = FD->getParamDecl(I - 1)->getName();
1435     if (!ParamName.empty() && !PrevParamName.empty() &&
1436         filter::prefixSuffixCoverUnderThreshold(
1437             Check.NamePrefixSuffixSilenceDissimilarityTreshold, PrevParamName,
1438             ParamName)) {
1439       LLVM_DEBUG(llvm::dbgs() << "Parameter '" << ParamName
1440                               << "' follows a pattern with previous parameter '"
1441                               << PrevParamName << "'. Break!\n");
1442       break;
1443     }
1444 
1445     // Now try to go forward and build the range of [Start, ..., I, I + 1, ...]
1446     // parameters that can be messed up at a call site.
1447     MixableParameterRange::MixVector MixesOfIth;
1448     for (std::size_t J = StartIndex; J < I; ++J) {
1449       const ParmVarDecl *Jth = FD->getParamDecl(J);
1450       LLVM_DEBUG(llvm::dbgs()
1451                  << "Check mix of #" << J << " against #" << I << "...\n");
1452 
1453       if (isSimilarlyUsedParameter(UsageBasedSuppressor, Ith, Jth)) {
1454         // Consider the two similarly used parameters to not be possible in a
1455         // mix-up at the user's request, if they enabled this heuristic.
1456         LLVM_DEBUG(llvm::dbgs() << "Parameters #" << I << " and #" << J
1457                                 << " deemed related, ignoring...\n");
1458 
1459         // If the parameter #I and #J mixes, then I is mixable with something
1460         // in the current range, so the range has to be broken and I not
1461         // included.
1462         MixesOfIth.clear();
1463         break;
1464       }
1465 
1466       Mix M{Jth, Ith,
1467             calculateMixability(Check, Jth->getType(), Ith->getType(), Ctx,
1468                                 Check.ModelImplicitConversions
1469                                     ? ImplicitConversionModellingMode::All
1470                                     : ImplicitConversionModellingMode::None)};
1471       LLVM_DEBUG(llvm::dbgs() << "Mix flags (raw)           : "
1472                               << formatMixFlags(M.flags()) << '\n');
1473       M.sanitize();
1474       LLVM_DEBUG(llvm::dbgs() << "Mix flags (after sanitize): "
1475                               << formatMixFlags(M.flags()) << '\n');
1476 
1477       assert(M.flagsValid() && "All flags decayed!");
1478 
1479       if (M.mixable())
1480         MixesOfIth.emplace_back(std::move(M));
1481     }
1482 
1483     if (MixesOfIth.empty()) {
1484       // If there weren't any new mixes stored for Ith, the range is
1485       // [Start, ..., I].
1486       LLVM_DEBUG(llvm::dbgs()
1487                  << "Param #" << I
1488                  << " does not mix with any in the current range. Break!\n");
1489       break;
1490     }
1491 
1492     Ret.Mixes.insert(Ret.Mixes.end(), MixesOfIth.begin(), MixesOfIth.end());
1493     ++Ret.NumParamsChecked; // Otherwise a new param was iterated.
1494   }
1495 
1496   return Ret;
1497 }
1498 
1499 } // namespace model
1500 
1501 /// Matches DeclRefExprs and their ignorable wrappers to ParmVarDecls.
1502 AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher<Stmt>, paramRefExpr) {
1503   return expr(ignoringParenImpCasts(ignoringElidableConstructorCall(
1504       declRefExpr(to(parmVarDecl().bind("param"))))));
1505 }
1506 
1507 namespace filter {
1508 
1509 /// Returns whether the parameter's name or the parameter's type's name is
1510 /// configured by the user to be ignored from analysis and diagnostic.
1511 static bool isIgnoredParameter(const TheCheck &Check, const ParmVarDecl *Node) {
1512   LLVM_DEBUG(llvm::dbgs() << "Checking if '" << Node->getName()
1513                           << "' is ignored.\n");
1514 
1515   if (!Node->getIdentifier())
1516     return llvm::is_contained(Check.IgnoredParameterNames, "\"\"");
1517 
1518   StringRef NodeName = Node->getName();
1519   if (llvm::is_contained(Check.IgnoredParameterNames, NodeName)) {
1520     LLVM_DEBUG(llvm::dbgs() << "\tName ignored.\n");
1521     return true;
1522   }
1523 
1524   StringRef NodeTypeName = [Node] {
1525     const ASTContext &Ctx = Node->getASTContext();
1526     const SourceManager &SM = Ctx.getSourceManager();
1527     SourceLocation B = Node->getTypeSpecStartLoc();
1528     SourceLocation E = Node->getTypeSpecEndLoc();
1529     LangOptions LO;
1530 
1531     LLVM_DEBUG(llvm::dbgs() << "\tType name code is '"
1532                             << Lexer::getSourceText(
1533                                    CharSourceRange::getTokenRange(B, E), SM, LO)
1534                             << "'...\n");
1535     if (B.isMacroID()) {
1536       LLVM_DEBUG(llvm::dbgs() << "\t\tBeginning is macro.\n");
1537       B = SM.getTopMacroCallerLoc(B);
1538     }
1539     if (E.isMacroID()) {
1540       LLVM_DEBUG(llvm::dbgs() << "\t\tEnding is macro.\n");
1541       E = Lexer::getLocForEndOfToken(SM.getTopMacroCallerLoc(E), 0, SM, LO);
1542     }
1543     LLVM_DEBUG(llvm::dbgs() << "\tType name code is '"
1544                             << Lexer::getSourceText(
1545                                    CharSourceRange::getTokenRange(B, E), SM, LO)
1546                             << "'...\n");
1547 
1548     return Lexer::getSourceText(CharSourceRange::getTokenRange(B, E), SM, LO);
1549   }();
1550 
1551   LLVM_DEBUG(llvm::dbgs() << "\tType name is '" << NodeTypeName << "'\n");
1552   if (!NodeTypeName.empty()) {
1553     if (llvm::any_of(Check.IgnoredParameterTypeSuffixes,
1554                      [NodeTypeName](StringRef E) {
1555                        return !E.empty() && NodeTypeName.endswith(E);
1556                      })) {
1557       LLVM_DEBUG(llvm::dbgs() << "\tType suffix ignored.\n");
1558       return true;
1559     }
1560   }
1561 
1562   return false;
1563 }
1564 
1565 /// This namespace contains the implementations for the suppression of
1566 /// diagnostics from similarly-used ("related") parameters.
1567 namespace relatedness_heuristic {
1568 
1569 static constexpr std::size_t SmallDataStructureSize = 4;
1570 
1571 template <typename T, std::size_t N = SmallDataStructureSize>
1572 using ParamToSmallSetMap =
1573     llvm::DenseMap<const ParmVarDecl *, llvm::SmallSet<T, N>>;
1574 
1575 /// Returns whether the sets mapped to the two elements in the map have at
1576 /// least one element in common.
1577 template <typename MapTy, typename ElemTy>
1578 bool lazyMapOfSetsIntersectionExists(const MapTy &Map, const ElemTy &E1,
1579                                      const ElemTy &E2) {
1580   auto E1Iterator = Map.find(E1);
1581   auto E2Iterator = Map.find(E2);
1582   if (E1Iterator == Map.end() || E2Iterator == Map.end())
1583     return false;
1584 
1585   for (const auto &E1SetElem : E1Iterator->second)
1586     if (llvm::is_contained(E2Iterator->second, E1SetElem))
1587       return true;
1588 
1589   return false;
1590 }
1591 
1592 /// Implements the heuristic that marks two parameters related if there is
1593 /// a usage for both in the same strict expression subtree. A strict
1594 /// expression subtree is a tree which only includes Expr nodes, i.e. no
1595 /// Stmts and no Decls.
1596 class AppearsInSameExpr : public RecursiveASTVisitor<AppearsInSameExpr> {
1597   using Base = RecursiveASTVisitor<AppearsInSameExpr>;
1598 
1599   const FunctionDecl *FD;
1600   const Expr *CurrentExprOnlyTreeRoot = nullptr;
1601   llvm::DenseMap<const ParmVarDecl *,
1602                  llvm::SmallPtrSet<const Expr *, SmallDataStructureSize>>
1603       ParentExprsForParamRefs;
1604 
1605 public:
1606   void setup(const FunctionDecl *FD) {
1607     this->FD = FD;
1608     TraverseFunctionDecl(const_cast<FunctionDecl *>(FD));
1609   }
1610 
1611   bool operator()(const ParmVarDecl *Param1, const ParmVarDecl *Param2) const {
1612     return lazyMapOfSetsIntersectionExists(ParentExprsForParamRefs, Param1,
1613                                            Param2);
1614   }
1615 
1616   bool TraverseDecl(Decl *D) {
1617     CurrentExprOnlyTreeRoot = nullptr;
1618     return Base::TraverseDecl(D);
1619   }
1620 
1621   bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr) {
1622     if (auto *E = dyn_cast_or_null<Expr>(S)) {
1623       bool RootSetInCurrentStackFrame = false;
1624       if (!CurrentExprOnlyTreeRoot) {
1625         CurrentExprOnlyTreeRoot = E;
1626         RootSetInCurrentStackFrame = true;
1627       }
1628 
1629       bool Ret = Base::TraverseStmt(S);
1630 
1631       if (RootSetInCurrentStackFrame)
1632         CurrentExprOnlyTreeRoot = nullptr;
1633 
1634       return Ret;
1635     }
1636 
1637     // A Stmt breaks the strictly Expr subtree.
1638     CurrentExprOnlyTreeRoot = nullptr;
1639     return Base::TraverseStmt(S);
1640   }
1641 
1642   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
1643     if (!CurrentExprOnlyTreeRoot)
1644       return true;
1645 
1646     if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
1647       if (llvm::find(FD->parameters(), PVD))
1648         ParentExprsForParamRefs[PVD].insert(CurrentExprOnlyTreeRoot);
1649 
1650     return true;
1651   }
1652 };
1653 
1654 /// Implements the heuristic that marks two parameters related if there are
1655 /// two separate calls to the same function (overload) and the parameters are
1656 /// passed to the same index in both calls, i.e f(a, b) and f(a, c) passes
1657 /// b and c to the same index (2) of f(), marking them related.
1658 class PassedToSameFunction {
1659   ParamToSmallSetMap<std::pair<const FunctionDecl *, unsigned>> TargetParams;
1660 
1661 public:
1662   void setup(const FunctionDecl *FD) {
1663     auto ParamsAsArgsInFnCalls =
1664         match(functionDecl(forEachDescendant(
1665                   callExpr(forEachArgumentWithParam(
1666                                paramRefExpr(), parmVarDecl().bind("passed-to")))
1667                       .bind("call-expr"))),
1668               *FD, FD->getASTContext());
1669     for (const auto &Match : ParamsAsArgsInFnCalls) {
1670       const auto *PassedParamOfThisFn = Match.getNodeAs<ParmVarDecl>("param");
1671       const auto *CE = Match.getNodeAs<CallExpr>("call-expr");
1672       const auto *PassedToParam = Match.getNodeAs<ParmVarDecl>("passed-to");
1673       assert(PassedParamOfThisFn && CE && PassedToParam);
1674 
1675       const FunctionDecl *CalledFn = CE->getDirectCallee();
1676       if (!CalledFn)
1677         continue;
1678 
1679       std::optional<unsigned> TargetIdx;
1680       unsigned NumFnParams = CalledFn->getNumParams();
1681       for (unsigned Idx = 0; Idx < NumFnParams; ++Idx)
1682         if (CalledFn->getParamDecl(Idx) == PassedToParam)
1683           TargetIdx.emplace(Idx);
1684 
1685       assert(TargetIdx && "Matched, but didn't find index?");
1686       TargetParams[PassedParamOfThisFn].insert(
1687           {CalledFn->getCanonicalDecl(), *TargetIdx});
1688     }
1689   }
1690 
1691   bool operator()(const ParmVarDecl *Param1, const ParmVarDecl *Param2) const {
1692     return lazyMapOfSetsIntersectionExists(TargetParams, Param1, Param2);
1693   }
1694 };
1695 
1696 /// Implements the heuristic that marks two parameters related if the same
1697 /// member is accessed (referred to) inside the current function's body.
1698 class AccessedSameMemberOf {
1699   ParamToSmallSetMap<const Decl *> AccessedMembers;
1700 
1701 public:
1702   void setup(const FunctionDecl *FD) {
1703     auto MembersCalledOnParams = match(
1704         functionDecl(forEachDescendant(
1705             memberExpr(hasObjectExpression(paramRefExpr())).bind("mem-expr"))),
1706         *FD, FD->getASTContext());
1707 
1708     for (const auto &Match : MembersCalledOnParams) {
1709       const auto *AccessedParam = Match.getNodeAs<ParmVarDecl>("param");
1710       const auto *ME = Match.getNodeAs<MemberExpr>("mem-expr");
1711       assert(AccessedParam && ME);
1712       AccessedMembers[AccessedParam].insert(
1713           ME->getMemberDecl()->getCanonicalDecl());
1714     }
1715   }
1716 
1717   bool operator()(const ParmVarDecl *Param1, const ParmVarDecl *Param2) const {
1718     return lazyMapOfSetsIntersectionExists(AccessedMembers, Param1, Param2);
1719   }
1720 };
1721 
1722 /// Implements the heuristic that marks two parameters related if different
1723 /// ReturnStmts return them from the function.
1724 class Returned {
1725   llvm::SmallVector<const ParmVarDecl *, SmallDataStructureSize> ReturnedParams;
1726 
1727 public:
1728   void setup(const FunctionDecl *FD) {
1729     // TODO: Handle co_return.
1730     auto ParamReturns = match(functionDecl(forEachDescendant(
1731                                   returnStmt(hasReturnValue(paramRefExpr())))),
1732                               *FD, FD->getASTContext());
1733     for (const auto &Match : ParamReturns) {
1734       const auto *ReturnedParam = Match.getNodeAs<ParmVarDecl>("param");
1735       assert(ReturnedParam);
1736 
1737       if (find(FD->parameters(), ReturnedParam) == FD->param_end())
1738         // Inside the subtree of a FunctionDecl there might be ReturnStmts of
1739         // a parameter that isn't the parameter of the function, e.g. in the
1740         // case of lambdas.
1741         continue;
1742 
1743       ReturnedParams.emplace_back(ReturnedParam);
1744     }
1745   }
1746 
1747   bool operator()(const ParmVarDecl *Param1, const ParmVarDecl *Param2) const {
1748     return llvm::is_contained(ReturnedParams, Param1) &&
1749            llvm::is_contained(ReturnedParams, Param2);
1750   }
1751 };
1752 
1753 } // namespace relatedness_heuristic
1754 
1755 /// Helper class that is used to detect if two parameters of the same function
1756 /// are used in a similar fashion, to suppress the result.
1757 class SimilarlyUsedParameterPairSuppressor {
1758   const bool Enabled;
1759   relatedness_heuristic::AppearsInSameExpr SameExpr;
1760   relatedness_heuristic::PassedToSameFunction PassToFun;
1761   relatedness_heuristic::AccessedSameMemberOf SameMember;
1762   relatedness_heuristic::Returned Returns;
1763 
1764 public:
1765   SimilarlyUsedParameterPairSuppressor(const FunctionDecl *FD, bool Enable)
1766       : Enabled(Enable) {
1767     if (!Enable)
1768       return;
1769 
1770     SameExpr.setup(FD);
1771     PassToFun.setup(FD);
1772     SameMember.setup(FD);
1773     Returns.setup(FD);
1774   }
1775 
1776   /// Returns whether the specified two parameters are deemed similarly used
1777   /// or related by the heuristics.
1778   bool operator()(const ParmVarDecl *Param1, const ParmVarDecl *Param2) const {
1779     if (!Enabled)
1780       return false;
1781 
1782     LLVM_DEBUG(llvm::dbgs()
1783                << "::: Matching similar usage / relatedness heuristic...\n");
1784 
1785     if (SameExpr(Param1, Param2)) {
1786       LLVM_DEBUG(llvm::dbgs() << "::: Used in the same expression.\n");
1787       return true;
1788     }
1789 
1790     if (PassToFun(Param1, Param2)) {
1791       LLVM_DEBUG(llvm::dbgs()
1792                  << "::: Passed to same function in different calls.\n");
1793       return true;
1794     }
1795 
1796     if (SameMember(Param1, Param2)) {
1797       LLVM_DEBUG(llvm::dbgs()
1798                  << "::: Same member field access or method called.\n");
1799       return true;
1800     }
1801 
1802     if (Returns(Param1, Param2)) {
1803       LLVM_DEBUG(llvm::dbgs() << "::: Both parameter returned.\n");
1804       return true;
1805     }
1806 
1807     LLVM_DEBUG(llvm::dbgs() << "::: None.\n");
1808     return false;
1809   }
1810 };
1811 
1812 // (This function hoists the call to operator() of the wrapper, so we do not
1813 // need to define the previous class at the top of the file.)
1814 static inline bool
1815 isSimilarlyUsedParameter(const SimilarlyUsedParameterPairSuppressor &Suppressor,
1816                          const ParmVarDecl *Param1, const ParmVarDecl *Param2) {
1817   return Suppressor(Param1, Param2);
1818 }
1819 
1820 static void padStringAtEnd(SmallVectorImpl<char> &Str, std::size_t ToLen) {
1821   while (Str.size() < ToLen)
1822     Str.emplace_back('\0');
1823 }
1824 
1825 static void padStringAtBegin(SmallVectorImpl<char> &Str, std::size_t ToLen) {
1826   while (Str.size() < ToLen)
1827     Str.insert(Str.begin(), '\0');
1828 }
1829 
1830 static bool isCommonPrefixWithoutSomeCharacters(std::size_t N, StringRef S1,
1831                                                 StringRef S2) {
1832   assert(S1.size() >= N && S2.size() >= N);
1833   StringRef S1Prefix = S1.take_front(S1.size() - N),
1834             S2Prefix = S2.take_front(S2.size() - N);
1835   return S1Prefix == S2Prefix && !S1Prefix.empty();
1836 }
1837 
1838 static bool isCommonSuffixWithoutSomeCharacters(std::size_t N, StringRef S1,
1839                                                 StringRef S2) {
1840   assert(S1.size() >= N && S2.size() >= N);
1841   StringRef S1Suffix = S1.take_back(S1.size() - N),
1842             S2Suffix = S2.take_back(S2.size() - N);
1843   return S1Suffix == S2Suffix && !S1Suffix.empty();
1844 }
1845 
1846 /// Returns whether the two strings are prefixes or suffixes of each other with
1847 /// at most Threshold characters differing on the non-common end.
1848 static bool prefixSuffixCoverUnderThreshold(std::size_t Threshold,
1849                                             StringRef Str1, StringRef Str2) {
1850   if (Threshold == 0)
1851     return false;
1852 
1853   // Pad the two strings to the longer length.
1854   std::size_t BiggerLength = std::max(Str1.size(), Str2.size());
1855 
1856   if (BiggerLength <= Threshold)
1857     // If the length of the strings is still smaller than the threshold, they
1858     // would be covered by an empty prefix/suffix with the rest differing.
1859     // (E.g. "A" and "X" with Threshold = 1 would mean we think they are
1860     // similar and do not warn about them, which is a too eager assumption.)
1861     return false;
1862 
1863   SmallString<32> S1PadE{Str1}, S2PadE{Str2};
1864   padStringAtEnd(S1PadE, BiggerLength);
1865   padStringAtEnd(S2PadE, BiggerLength);
1866 
1867   if (isCommonPrefixWithoutSomeCharacters(
1868           Threshold, StringRef{S1PadE.begin(), BiggerLength},
1869           StringRef{S2PadE.begin(), BiggerLength}))
1870     return true;
1871 
1872   SmallString<32> S1PadB{Str1}, S2PadB{Str2};
1873   padStringAtBegin(S1PadB, BiggerLength);
1874   padStringAtBegin(S2PadB, BiggerLength);
1875 
1876   if (isCommonSuffixWithoutSomeCharacters(
1877           Threshold, StringRef{S1PadB.begin(), BiggerLength},
1878           StringRef{S2PadB.begin(), BiggerLength}))
1879     return true;
1880 
1881   return false;
1882 }
1883 
1884 } // namespace filter
1885 
1886 /// Matches functions that have at least the specified amount of parameters.
1887 AST_MATCHER_P(FunctionDecl, parameterCountGE, unsigned, N) {
1888   return Node.getNumParams() >= N;
1889 }
1890 
1891 /// Matches *any* overloaded unary and binary operators.
1892 AST_MATCHER(FunctionDecl, isOverloadedUnaryOrBinaryOperator) {
1893   switch (Node.getOverloadedOperator()) {
1894   case OO_None:
1895   case OO_New:
1896   case OO_Delete:
1897   case OO_Array_New:
1898   case OO_Array_Delete:
1899   case OO_Conditional:
1900   case OO_Coawait:
1901     return false;
1902 
1903   default:
1904     return Node.getNumParams() <= 2;
1905   }
1906 }
1907 
1908 /// Returns the DefaultMinimumLength if the Value of requested minimum length
1909 /// is less than 2. Minimum lengths of 0 or 1 are not accepted.
1910 static inline unsigned clampMinimumLength(const unsigned Value) {
1911   return Value < 2 ? DefaultMinimumLength : Value;
1912 }
1913 
1914 // FIXME: Maybe unneeded, getNameForDiagnostic() is expected to change to return
1915 // a crafted location when the node itself is unnamed. (See D84658, D85033.)
1916 /// Returns the diagnostic-friendly name of the node, or empty string.
1917 static SmallString<64> getName(const NamedDecl *ND) {
1918   SmallString<64> Name;
1919   llvm::raw_svector_ostream OS{Name};
1920   ND->getNameForDiagnostic(OS, ND->getASTContext().getPrintingPolicy(), false);
1921   return Name;
1922 }
1923 
1924 /// Returns the diagnostic-friendly name of the node, or a constant value.
1925 static SmallString<64> getNameOrUnnamed(const NamedDecl *ND) {
1926   auto Name = getName(ND);
1927   if (Name.empty())
1928     Name = "<unnamed>";
1929   return Name;
1930 }
1931 
1932 /// Returns whether a particular Mix between two parameters should have the
1933 /// types involved diagnosed to the user. This is only a flag check.
1934 static inline bool needsToPrintTypeInDiagnostic(const model::Mix &M) {
1935   using namespace model;
1936   return static_cast<bool>(
1937       M.flags() &
1938       (MixFlags::TypeAlias | MixFlags::ReferenceBind | MixFlags::Qualifiers));
1939 }
1940 
1941 /// Returns whether a particular Mix between the two parameters should have
1942 /// implicit conversions elaborated.
1943 static inline bool needsToElaborateImplicitConversion(const model::Mix &M) {
1944   return hasFlag(M.flags(), model::MixFlags::ImplicitConversion);
1945 }
1946 
1947 namespace {
1948 
1949 /// This class formats a conversion sequence into a "Ty1 -> Ty2 -> Ty3" line
1950 /// that can be used in diagnostics.
1951 struct FormattedConversionSequence {
1952   std::string DiagnosticText;
1953 
1954   /// The formatted sequence is trivial if it is "Ty1 -> Ty2", but Ty1 and
1955   /// Ty2 are the types that are shown in the code. A trivial diagnostic
1956   /// does not need to be printed.
1957   bool Trivial;
1958 
1959   FormattedConversionSequence(const PrintingPolicy &PP,
1960                               StringRef StartTypeAsDiagnosed,
1961                               const model::ConversionSequence &Conv,
1962                               StringRef DestinationTypeAsDiagnosed) {
1963     Trivial = true;
1964     llvm::raw_string_ostream OS{DiagnosticText};
1965 
1966     // Print the type name as it is printed in other places in the diagnostic.
1967     OS << '\'' << StartTypeAsDiagnosed << '\'';
1968     std::string LastAddedType = StartTypeAsDiagnosed.str();
1969     std::size_t NumElementsAdded = 1;
1970 
1971     // However, the parameter's defined type might not be what the implicit
1972     // conversion started with, e.g. if a typedef is found to convert.
1973     std::string SeqBeginTypeStr = Conv.Begin.getAsString(PP);
1974     std::string SeqEndTypeStr = Conv.End.getAsString(PP);
1975     if (StartTypeAsDiagnosed != SeqBeginTypeStr) {
1976       OS << " (as '" << SeqBeginTypeStr << "')";
1977       LastAddedType = SeqBeginTypeStr;
1978       Trivial = false;
1979     }
1980 
1981     auto AddType = [&](StringRef ToAdd) {
1982       if (LastAddedType != ToAdd && ToAdd != SeqEndTypeStr) {
1983         OS << " -> '" << ToAdd << "'";
1984         LastAddedType = ToAdd.str();
1985         ++NumElementsAdded;
1986       }
1987     };
1988     for (QualType InvolvedType : Conv.getInvolvedTypesInSequence())
1989       // Print every type that's unique in the sequence into the diagnosis.
1990       AddType(InvolvedType.getAsString(PP));
1991 
1992     if (LastAddedType != DestinationTypeAsDiagnosed) {
1993       OS << " -> '" << DestinationTypeAsDiagnosed << "'";
1994       LastAddedType = DestinationTypeAsDiagnosed.str();
1995       ++NumElementsAdded;
1996     }
1997 
1998     // Same reasoning as with the Begin, e.g. if the converted-to type is a
1999     // typedef, it will not be the same inside the conversion sequence (where
2000     // the model already tore off typedefs) as in the code.
2001     if (DestinationTypeAsDiagnosed != SeqEndTypeStr) {
2002       OS << " (as '" << SeqEndTypeStr << "')";
2003       LastAddedType = SeqEndTypeStr;
2004       Trivial = false;
2005     }
2006 
2007     if (Trivial && NumElementsAdded > 2)
2008       // If the thing is still marked trivial but we have more than the
2009       // from and to types added, it should not be trivial, and elaborated
2010       // when printing the diagnostic.
2011       Trivial = false;
2012   }
2013 };
2014 
2015 /// Retains the elements called with and returns whether the call is done with
2016 /// a new element.
2017 template <typename E, std::size_t N> class InsertOnce {
2018   llvm::SmallSet<E, N> CalledWith;
2019 
2020 public:
2021   bool operator()(E El) { return CalledWith.insert(std::move(El)).second; }
2022 
2023   bool calledWith(const E &El) const { return CalledWith.contains(El); }
2024 };
2025 
2026 struct SwappedEqualQualTypePair {
2027   QualType LHSType, RHSType;
2028 
2029   bool operator==(const SwappedEqualQualTypePair &Other) const {
2030     return (LHSType == Other.LHSType && RHSType == Other.RHSType) ||
2031            (LHSType == Other.RHSType && RHSType == Other.LHSType);
2032   }
2033 
2034   bool operator<(const SwappedEqualQualTypePair &Other) const {
2035     return LHSType < Other.LHSType && RHSType < Other.RHSType;
2036   }
2037 };
2038 
2039 struct TypeAliasDiagnosticTuple {
2040   QualType LHSType, RHSType, CommonType;
2041 
2042   bool operator==(const TypeAliasDiagnosticTuple &Other) const {
2043     return CommonType == Other.CommonType &&
2044            ((LHSType == Other.LHSType && RHSType == Other.RHSType) ||
2045             (LHSType == Other.RHSType && RHSType == Other.LHSType));
2046   }
2047 
2048   bool operator<(const TypeAliasDiagnosticTuple &Other) const {
2049     return CommonType < Other.CommonType && LHSType < Other.LHSType &&
2050            RHSType < Other.RHSType;
2051   }
2052 };
2053 
2054 /// Helper class to only emit a diagnostic related to MixFlags::TypeAlias once.
2055 class UniqueTypeAliasDiagnosticHelper
2056     : public InsertOnce<TypeAliasDiagnosticTuple, 8> {
2057   using Base = InsertOnce<TypeAliasDiagnosticTuple, 8>;
2058 
2059 public:
2060   /// Returns whether the diagnostic for LHSType and RHSType which are both
2061   /// referring to CommonType being the same has not been emitted already.
2062   bool operator()(QualType LHSType, QualType RHSType, QualType CommonType) {
2063     if (CommonType.isNull() || CommonType == LHSType || CommonType == RHSType)
2064       return Base::operator()({LHSType, RHSType, {}});
2065 
2066     TypeAliasDiagnosticTuple ThreeTuple{LHSType, RHSType, CommonType};
2067     if (!Base::operator()(ThreeTuple))
2068       return false;
2069 
2070     bool AlreadySaidLHSAndCommonIsSame = calledWith({LHSType, CommonType, {}});
2071     bool AlreadySaidRHSAndCommonIsSame = calledWith({RHSType, CommonType, {}});
2072     if (AlreadySaidLHSAndCommonIsSame && AlreadySaidRHSAndCommonIsSame) {
2073       // "SomeInt == int" && "SomeOtherInt == int" => "Common(SomeInt,
2074       // SomeOtherInt) == int", no need to diagnose it. Save the 3-tuple only
2075       // for shortcut if it ever appears again.
2076       return false;
2077     }
2078 
2079     return true;
2080   }
2081 };
2082 
2083 } // namespace
2084 
2085 EasilySwappableParametersCheck::EasilySwappableParametersCheck(
2086     StringRef Name, ClangTidyContext *Context)
2087     : ClangTidyCheck(Name, Context),
2088       MinimumLength(clampMinimumLength(
2089           Options.get("MinimumLength", DefaultMinimumLength))),
2090       IgnoredParameterNames(optutils::parseStringList(
2091           Options.get("IgnoredParameterNames", DefaultIgnoredParameterNames))),
2092       IgnoredParameterTypeSuffixes(optutils::parseStringList(
2093           Options.get("IgnoredParameterTypeSuffixes",
2094                       DefaultIgnoredParameterTypeSuffixes))),
2095       QualifiersMix(Options.get("QualifiersMix", DefaultQualifiersMix)),
2096       ModelImplicitConversions(Options.get("ModelImplicitConversions",
2097                                            DefaultModelImplicitConversions)),
2098       SuppressParametersUsedTogether(
2099           Options.get("SuppressParametersUsedTogether",
2100                       DefaultSuppressParametersUsedTogether)),
2101       NamePrefixSuffixSilenceDissimilarityTreshold(
2102           Options.get("NamePrefixSuffixSilenceDissimilarityTreshold",
2103                       DefaultNamePrefixSuffixSilenceDissimilarityTreshold)) {}
2104 
2105 void EasilySwappableParametersCheck::storeOptions(
2106     ClangTidyOptions::OptionMap &Opts) {
2107   Options.store(Opts, "MinimumLength", MinimumLength);
2108   Options.store(Opts, "IgnoredParameterNames",
2109                 optutils::serializeStringList(IgnoredParameterNames));
2110   Options.store(Opts, "IgnoredParameterTypeSuffixes",
2111                 optutils::serializeStringList(IgnoredParameterTypeSuffixes));
2112   Options.store(Opts, "QualifiersMix", QualifiersMix);
2113   Options.store(Opts, "ModelImplicitConversions", ModelImplicitConversions);
2114   Options.store(Opts, "SuppressParametersUsedTogether",
2115                 SuppressParametersUsedTogether);
2116   Options.store(Opts, "NamePrefixSuffixSilenceDissimilarityTreshold",
2117                 NamePrefixSuffixSilenceDissimilarityTreshold);
2118 }
2119 
2120 void EasilySwappableParametersCheck::registerMatchers(MatchFinder *Finder) {
2121   const auto BaseConstraints = functionDecl(
2122       // Only report for definition nodes, as fixing the issues reported
2123       // requires the user to be able to change code.
2124       isDefinition(), parameterCountGE(MinimumLength),
2125       unless(isOverloadedUnaryOrBinaryOperator()));
2126 
2127   Finder->addMatcher(
2128       functionDecl(BaseConstraints,
2129                    unless(ast_matchers::isTemplateInstantiation()))
2130           .bind("func"),
2131       this);
2132   Finder->addMatcher(
2133       functionDecl(BaseConstraints, isExplicitTemplateSpecialization())
2134           .bind("func"),
2135       this);
2136 }
2137 
2138 void EasilySwappableParametersCheck::check(
2139     const MatchFinder::MatchResult &Result) {
2140   using namespace model;
2141   using namespace filter;
2142 
2143   const auto *FD = Result.Nodes.getNodeAs<FunctionDecl>("func");
2144   assert(FD);
2145 
2146   const PrintingPolicy &PP = FD->getASTContext().getPrintingPolicy();
2147   std::size_t NumParams = FD->getNumParams();
2148   std::size_t MixableRangeStartIndex = 0;
2149 
2150   // Spawn one suppressor and if the user requested, gather information from
2151   // the AST for the parameters' usages.
2152   filter::SimilarlyUsedParameterPairSuppressor UsageBasedSuppressor{
2153       FD, SuppressParametersUsedTogether};
2154 
2155   LLVM_DEBUG(llvm::dbgs() << "Begin analysis of " << getName(FD) << " with "
2156                           << NumParams << " parameters...\n");
2157   while (MixableRangeStartIndex < NumParams) {
2158     if (isIgnoredParameter(*this, FD->getParamDecl(MixableRangeStartIndex))) {
2159       LLVM_DEBUG(llvm::dbgs()
2160                  << "Parameter #" << MixableRangeStartIndex << " ignored.\n");
2161       ++MixableRangeStartIndex;
2162       continue;
2163     }
2164 
2165     MixableParameterRange R = modelMixingRange(
2166         *this, FD, MixableRangeStartIndex, UsageBasedSuppressor);
2167     assert(R.NumParamsChecked > 0 && "Ensure forward progress!");
2168     MixableRangeStartIndex += R.NumParamsChecked;
2169     if (R.NumParamsChecked < MinimumLength) {
2170       LLVM_DEBUG(llvm::dbgs() << "Ignoring range of " << R.NumParamsChecked
2171                               << " lower than limit.\n");
2172       continue;
2173     }
2174 
2175     bool NeedsAnyTypeNote = llvm::any_of(R.Mixes, needsToPrintTypeInDiagnostic);
2176     bool HasAnyImplicits =
2177         llvm::any_of(R.Mixes, needsToElaborateImplicitConversion);
2178     const ParmVarDecl *First = R.getFirstParam(), *Last = R.getLastParam();
2179     std::string FirstParamTypeAsWritten = First->getType().getAsString(PP);
2180     {
2181       StringRef DiagText;
2182 
2183       if (HasAnyImplicits)
2184         DiagText = "%0 adjacent parameters of %1 of convertible types are "
2185                    "easily swapped by mistake";
2186       else if (NeedsAnyTypeNote)
2187         DiagText = "%0 adjacent parameters of %1 of similar type are easily "
2188                    "swapped by mistake";
2189       else
2190         DiagText = "%0 adjacent parameters of %1 of similar type ('%2') are "
2191                    "easily swapped by mistake";
2192 
2193       auto Diag = diag(First->getOuterLocStart(), DiagText)
2194                   << static_cast<unsigned>(R.NumParamsChecked) << FD;
2195       if (!NeedsAnyTypeNote)
2196         Diag << FirstParamTypeAsWritten;
2197 
2198       CharSourceRange HighlightRange = CharSourceRange::getTokenRange(
2199           First->getBeginLoc(), Last->getEndLoc());
2200       Diag << HighlightRange;
2201     }
2202 
2203     // There is a chance that the previous highlight did not succeed, e.g. when
2204     // the two parameters are on different lines. For clarity, show the user
2205     // the involved variable explicitly.
2206     diag(First->getLocation(), "the first parameter in the range is '%0'",
2207          DiagnosticIDs::Note)
2208         << getNameOrUnnamed(First)
2209         << CharSourceRange::getTokenRange(First->getLocation(),
2210                                           First->getLocation());
2211     diag(Last->getLocation(), "the last parameter in the range is '%0'",
2212          DiagnosticIDs::Note)
2213         << getNameOrUnnamed(Last)
2214         << CharSourceRange::getTokenRange(Last->getLocation(),
2215                                           Last->getLocation());
2216 
2217     // Helper classes to silence elaborative diagnostic notes that would be
2218     // too verbose.
2219     UniqueTypeAliasDiagnosticHelper UniqueTypeAlias;
2220     InsertOnce<SwappedEqualQualTypePair, 8> UniqueBindPower;
2221     InsertOnce<SwappedEqualQualTypePair, 8> UniqueImplicitConversion;
2222 
2223     for (const model::Mix &M : R.Mixes) {
2224       assert(M.mixable() && "Sentinel or false mix in result.");
2225       if (!needsToPrintTypeInDiagnostic(M) &&
2226           !needsToElaborateImplicitConversion(M))
2227         continue;
2228 
2229       // Typedefs might result in the type of the variable needing to be
2230       // emitted to a note diagnostic, so prepare it.
2231       const ParmVarDecl *LVar = M.First;
2232       const ParmVarDecl *RVar = M.Second;
2233       QualType LType = LVar->getType();
2234       QualType RType = RVar->getType();
2235       QualType CommonType = M.commonUnderlyingType();
2236       std::string LTypeStr = LType.getAsString(PP);
2237       std::string RTypeStr = RType.getAsString(PP);
2238       std::string CommonTypeStr = CommonType.getAsString(PP);
2239 
2240       if (hasFlag(M.flags(), MixFlags::TypeAlias) &&
2241           UniqueTypeAlias(LType, RType, CommonType)) {
2242         StringRef DiagText;
2243         bool ExplicitlyPrintCommonType = false;
2244         if (LTypeStr == CommonTypeStr || RTypeStr == CommonTypeStr) {
2245           if (hasFlag(M.flags(), MixFlags::Qualifiers))
2246             DiagText = "after resolving type aliases, '%0' and '%1' share a "
2247                        "common type";
2248           else
2249             DiagText =
2250                 "after resolving type aliases, '%0' and '%1' are the same";
2251         } else if (!CommonType.isNull()) {
2252           DiagText = "after resolving type aliases, the common type of '%0' "
2253                      "and '%1' is '%2'";
2254           ExplicitlyPrintCommonType = true;
2255         }
2256 
2257         auto Diag =
2258             diag(LVar->getOuterLocStart(), DiagText, DiagnosticIDs::Note)
2259             << LTypeStr << RTypeStr;
2260         if (ExplicitlyPrintCommonType)
2261           Diag << CommonTypeStr;
2262       }
2263 
2264       if ((hasFlag(M.flags(), MixFlags::ReferenceBind) ||
2265            hasFlag(M.flags(), MixFlags::Qualifiers)) &&
2266           UniqueBindPower({LType, RType})) {
2267         StringRef DiagText = "'%0' and '%1' parameters accept and bind the "
2268                              "same kind of values";
2269         diag(RVar->getOuterLocStart(), DiagText, DiagnosticIDs::Note)
2270             << LTypeStr << RTypeStr;
2271       }
2272 
2273       if (needsToElaborateImplicitConversion(M) &&
2274           UniqueImplicitConversion({LType, RType})) {
2275         const model::ConversionSequence &LTR =
2276             M.leftToRightConversionSequence();
2277         const model::ConversionSequence &RTL =
2278             M.rightToLeftConversionSequence();
2279         FormattedConversionSequence LTRFmt{PP, LTypeStr, LTR, RTypeStr};
2280         FormattedConversionSequence RTLFmt{PP, RTypeStr, RTL, LTypeStr};
2281 
2282         StringRef DiagText = "'%0' and '%1' may be implicitly converted";
2283         if (!LTRFmt.Trivial || !RTLFmt.Trivial)
2284           DiagText = "'%0' and '%1' may be implicitly converted: %2, %3";
2285 
2286         {
2287           auto Diag =
2288               diag(RVar->getOuterLocStart(), DiagText, DiagnosticIDs::Note)
2289               << LTypeStr << RTypeStr;
2290 
2291           if (!LTRFmt.Trivial || !RTLFmt.Trivial)
2292             Diag << LTRFmt.DiagnosticText << RTLFmt.DiagnosticText;
2293         }
2294 
2295         StringRef ConversionFunctionDiagText =
2296             "the implicit conversion involves the "
2297             "%select{|converting constructor|conversion operator}0 "
2298             "declared here";
2299         if (const FunctionDecl *LFD = LTR.getUserDefinedConversionFunction())
2300           diag(LFD->getLocation(), ConversionFunctionDiagText,
2301                DiagnosticIDs::Note)
2302               << static_cast<unsigned>(LTR.UDConvKind)
2303               << LTR.getUserDefinedConversionHighlight();
2304         if (const FunctionDecl *RFD = RTL.getUserDefinedConversionFunction())
2305           diag(RFD->getLocation(), ConversionFunctionDiagText,
2306                DiagnosticIDs::Note)
2307               << static_cast<unsigned>(RTL.UDConvKind)
2308               << RTL.getUserDefinedConversionHighlight();
2309       }
2310     }
2311   }
2312 }
2313 
2314 } // namespace bugprone
2315 } // namespace tidy
2316 } // namespace clang
2317