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