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