xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaTypeTraits.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 //===----- SemaTypeTraits.cpp - Semantic Analysis for C++ Type Traits -----===//
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 //  This file implements semantic analysis for C++ type traits.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/DeclCXX.h"
14 #include "clang/AST/TemplateBase.h"
15 #include "clang/AST/Type.h"
16 #include "clang/Basic/DiagnosticIDs.h"
17 #include "clang/Basic/DiagnosticParse.h"
18 #include "clang/Basic/DiagnosticSema.h"
19 #include "clang/Basic/TypeTraits.h"
20 #include "clang/Sema/EnterExpressionEvaluationContext.h"
21 #include "clang/Sema/Initialization.h"
22 #include "clang/Sema/Lookup.h"
23 #include "clang/Sema/Overload.h"
24 #include "clang/Sema/Sema.h"
25 #include "clang/Sema/SemaHLSL.h"
26 
27 using namespace clang;
28 
LookupSpecialMemberFromXValue(Sema & SemaRef,const CXXRecordDecl * RD,bool Assign)29 static CXXMethodDecl *LookupSpecialMemberFromXValue(Sema &SemaRef,
30                                                     const CXXRecordDecl *RD,
31                                                     bool Assign) {
32   RD = RD->getDefinition();
33   SourceLocation LookupLoc = RD->getLocation();
34 
35   CanQualType CanTy = SemaRef.getASTContext().getCanonicalType(
36       SemaRef.getASTContext().getTagDeclType(RD));
37   DeclarationName Name;
38   Expr *Arg = nullptr;
39   unsigned NumArgs;
40 
41   QualType ArgType = CanTy;
42   ExprValueKind VK = clang::VK_XValue;
43 
44   if (Assign)
45     Name =
46         SemaRef.getASTContext().DeclarationNames.getCXXOperatorName(OO_Equal);
47   else
48     Name =
49         SemaRef.getASTContext().DeclarationNames.getCXXConstructorName(CanTy);
50 
51   OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK);
52   NumArgs = 1;
53   Arg = &FakeArg;
54 
55   // Create the object argument
56   QualType ThisTy = CanTy;
57   Expr::Classification Classification =
58       OpaqueValueExpr(LookupLoc, ThisTy, VK_LValue)
59           .Classify(SemaRef.getASTContext());
60 
61   // Now we perform lookup on the name we computed earlier and do overload
62   // resolution. Lookup is only performed directly into the class since there
63   // will always be a (possibly implicit) declaration to shadow any others.
64   OverloadCandidateSet OCS(LookupLoc, OverloadCandidateSet::CSK_Normal);
65   DeclContext::lookup_result R = RD->lookup(Name);
66 
67   if (R.empty())
68     return nullptr;
69 
70   // Copy the candidates as our processing of them may load new declarations
71   // from an external source and invalidate lookup_result.
72   SmallVector<NamedDecl *, 8> Candidates(R.begin(), R.end());
73 
74   for (NamedDecl *CandDecl : Candidates) {
75     if (CandDecl->isInvalidDecl())
76       continue;
77 
78     DeclAccessPair Cand = DeclAccessPair::make(CandDecl, clang::AS_none);
79     auto CtorInfo = getConstructorInfo(Cand);
80     if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) {
81       if (Assign)
82         SemaRef.AddMethodCandidate(M, Cand, const_cast<CXXRecordDecl *>(RD),
83                                    ThisTy, Classification,
84                                    llvm::ArrayRef(&Arg, NumArgs), OCS, true);
85       else {
86         assert(CtorInfo);
87         SemaRef.AddOverloadCandidate(CtorInfo.Constructor, CtorInfo.FoundDecl,
88                                      llvm::ArrayRef(&Arg, NumArgs), OCS,
89                                      /*SuppressUserConversions*/ true);
90       }
91     } else if (FunctionTemplateDecl *Tmpl =
92                    dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) {
93       if (Assign)
94         SemaRef.AddMethodTemplateCandidate(
95             Tmpl, Cand, const_cast<CXXRecordDecl *>(RD), nullptr, ThisTy,
96             Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true);
97       else {
98         assert(CtorInfo);
99         SemaRef.AddTemplateOverloadCandidate(
100             CtorInfo.ConstructorTmpl, CtorInfo.FoundDecl, nullptr,
101             llvm::ArrayRef(&Arg, NumArgs), OCS, true);
102       }
103     }
104   }
105 
106   OverloadCandidateSet::iterator Best;
107   switch (OCS.BestViableFunction(SemaRef, LookupLoc, Best)) {
108   case OR_Success:
109   case OR_Deleted:
110     return cast<CXXMethodDecl>(Best->Function)->getCanonicalDecl();
111   default:
112     return nullptr;
113   }
114 }
115 
hasSuitableConstructorForRelocation(Sema & SemaRef,const CXXRecordDecl * D,bool AllowUserDefined)116 static bool hasSuitableConstructorForRelocation(Sema &SemaRef,
117                                                 const CXXRecordDecl *D,
118                                                 bool AllowUserDefined) {
119   assert(D->hasDefinition() && !D->isInvalidDecl());
120 
121   if (D->hasSimpleMoveConstructor() || D->hasSimpleCopyConstructor())
122     return true;
123 
124   CXXMethodDecl *Decl =
125       LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false);
126   return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
127          !Decl->isDeleted();
128 }
129 
hasSuitableMoveAssignmentOperatorForRelocation(Sema & SemaRef,const CXXRecordDecl * D,bool AllowUserDefined)130 static bool hasSuitableMoveAssignmentOperatorForRelocation(
131     Sema &SemaRef, const CXXRecordDecl *D, bool AllowUserDefined) {
132   assert(D->hasDefinition() && !D->isInvalidDecl());
133 
134   if (D->hasSimpleMoveAssignment() || D->hasSimpleCopyAssignment())
135     return true;
136 
137   CXXMethodDecl *Decl =
138       LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
139   if (!Decl)
140     return false;
141 
142   return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
143          !Decl->isDeleted();
144 }
145 
146 // [C++26][class.prop]
147 // A class C is default-movable if
148 // - overload resolution for direct-initializing an object of type C
149 // from an xvalue of type C selects a constructor that is a direct member of C
150 // and is neither user-provided nor deleted,
151 // - overload resolution for assigning to an lvalue of type C from an xvalue of
152 // type C selects an assignment operator function that is a direct member of C
153 // and is neither user-provided nor deleted, and C has a destructor that is
154 // neither user-provided nor deleted.
IsDefaultMovable(Sema & SemaRef,const CXXRecordDecl * D)155 static bool IsDefaultMovable(Sema &SemaRef, const CXXRecordDecl *D) {
156   if (!hasSuitableConstructorForRelocation(SemaRef, D,
157                                            /*AllowUserDefined=*/false))
158     return false;
159 
160   if (!hasSuitableMoveAssignmentOperatorForRelocation(
161           SemaRef, D, /*AllowUserDefined=*/false))
162     return false;
163 
164   CXXDestructorDecl *Dtr = D->getDestructor();
165 
166   if (!Dtr)
167     return true;
168 
169   Dtr = Dtr->getCanonicalDecl();
170 
171   if (Dtr->isUserProvided() && (!Dtr->isDefaulted() || Dtr->isDeleted()))
172     return false;
173 
174   return !Dtr->isDeleted();
175 }
176 
177 // [C++26][class.prop]
178 // A class is eligible for trivial relocation unless it...
IsEligibleForTrivialRelocation(Sema & SemaRef,const CXXRecordDecl * D)179 static bool IsEligibleForTrivialRelocation(Sema &SemaRef,
180                                            const CXXRecordDecl *D) {
181 
182   for (const CXXBaseSpecifier &B : D->bases()) {
183     const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
184     if (!BaseDecl)
185       continue;
186     // ... has any virtual base classes
187     // ... has a base class that is not a trivially relocatable class
188     if (B.isVirtual() || (!BaseDecl->isDependentType() &&
189                           !SemaRef.IsCXXTriviallyRelocatableType(B.getType())))
190       return false;
191   }
192 
193   bool IsUnion = D->isUnion();
194   for (const FieldDecl *Field : D->fields()) {
195     if (Field->getType()->isDependentType())
196       continue;
197     if (Field->getType()->isReferenceType())
198       continue;
199     // ... has a non-static data member of an object type that is not
200     // of a trivially relocatable type
201     if (!SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
202       return false;
203 
204     // A union contains values with address discriminated pointer auth
205     // cannot be relocated.
206     if (IsUnion && SemaRef.Context.containsAddressDiscriminatedPointerAuth(
207                        Field->getType()))
208       return false;
209   }
210   return !D->hasDeletedDestructor();
211 }
212 
213 // [C++26][class.prop]
214 // A class C is eligible for replacement unless
IsEligibleForReplacement(Sema & SemaRef,const CXXRecordDecl * D)215 static bool IsEligibleForReplacement(Sema &SemaRef, const CXXRecordDecl *D) {
216 
217   for (const CXXBaseSpecifier &B : D->bases()) {
218     const auto *BaseDecl = B.getType()->getAsCXXRecordDecl();
219     if (!BaseDecl)
220       continue;
221     // it has a base class that is not a replaceable class
222     if (!BaseDecl->isDependentType() &&
223         !SemaRef.IsCXXReplaceableType(B.getType()))
224       return false;
225   }
226 
227   for (const FieldDecl *Field : D->fields()) {
228     if (Field->getType()->isDependentType())
229       continue;
230 
231     // it has a non-static data member that is not of a replaceable type,
232     if (!SemaRef.IsCXXReplaceableType(Field->getType()))
233       return false;
234   }
235   return !D->hasDeletedDestructor();
236 }
237 
238 ASTContext::CXXRecordDeclRelocationInfo
CheckCXX2CRelocatableAndReplaceable(const CXXRecordDecl * D)239 Sema::CheckCXX2CRelocatableAndReplaceable(const CXXRecordDecl *D) {
240   ASTContext::CXXRecordDeclRelocationInfo Info{false, false};
241 
242   if (!getLangOpts().CPlusPlus || D->isInvalidDecl())
243     return Info;
244 
245   assert(D->hasDefinition());
246 
247   // This is part of "eligible for replacement", however we defer it
248   // to avoid extraneous computations.
249   auto HasSuitableSMP = [&] {
250     return hasSuitableConstructorForRelocation(*this, D,
251                                                /*AllowUserDefined=*/true) &&
252            hasSuitableMoveAssignmentOperatorForRelocation(
253                *this, D, /*AllowUserDefined=*/true);
254   };
255 
256   auto IsUnion = [&, Is = std::optional<bool>{}]() mutable {
257     if (!Is.has_value())
258       Is = D->isUnion() && !D->hasUserDeclaredCopyConstructor() &&
259            !D->hasUserDeclaredCopyAssignment() &&
260            !D->hasUserDeclaredMoveOperation() &&
261            !D->hasUserDeclaredDestructor();
262     return *Is;
263   };
264 
265   auto IsDefaultMovable = [&, Is = std::optional<bool>{}]() mutable {
266     if (!Is.has_value())
267       Is = ::IsDefaultMovable(*this, D);
268     return *Is;
269   };
270 
271   Info.IsRelocatable = [&] {
272     if (D->isDependentType())
273       return false;
274 
275     // if it is eligible for trivial relocation
276     if (!IsEligibleForTrivialRelocation(*this, D))
277       return false;
278 
279     // has the trivially_relocatable_if_eligible class-property-specifier,
280     if (D->hasAttr<TriviallyRelocatableAttr>())
281       return true;
282 
283     // is a union with no user-declared special member functions, or
284     if (IsUnion())
285       return true;
286 
287     // is default-movable.
288     return IsDefaultMovable();
289   }();
290 
291   Info.IsReplaceable = [&] {
292     if (D->isDependentType())
293       return false;
294 
295     // A class C is a replaceable class if it is eligible for replacement
296     if (!IsEligibleForReplacement(*this, D))
297       return false;
298 
299     // has the replaceable_if_eligible class-property-specifier
300     if (D->hasAttr<ReplaceableAttr>())
301       return HasSuitableSMP();
302 
303     // is a union with no user-declared special member functions, or
304     if (IsUnion())
305       return HasSuitableSMP();
306 
307     // is default-movable.
308     return IsDefaultMovable();
309   }();
310 
311   return Info;
312 }
313 
IsCXXTriviallyRelocatableType(const CXXRecordDecl & RD)314 bool Sema::IsCXXTriviallyRelocatableType(const CXXRecordDecl &RD) {
315   if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
316           getASTContext().getRelocationInfoForCXXRecord(&RD))
317     return Info->IsRelocatable;
318   ASTContext::CXXRecordDeclRelocationInfo Info =
319       CheckCXX2CRelocatableAndReplaceable(&RD);
320   getASTContext().setRelocationInfoForCXXRecord(&RD, Info);
321   return Info.IsRelocatable;
322 }
323 
IsCXXTriviallyRelocatableType(QualType Type)324 bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {
325   QualType BaseElementType = getASTContext().getBaseElementType(Type);
326 
327   if (Type->isVariableArrayType())
328     return false;
329 
330   if (BaseElementType.hasNonTrivialObjCLifetime())
331     return false;
332 
333   if (BaseElementType->isIncompleteType())
334     return false;
335 
336   if (Context.containsNonRelocatablePointerAuth(Type))
337     return false;
338 
339   if (BaseElementType->isScalarType() || BaseElementType->isVectorType())
340     return true;
341 
342   if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
343     return IsCXXTriviallyRelocatableType(*RD);
344 
345   return false;
346 }
347 
IsCXXReplaceableType(Sema & S,const CXXRecordDecl * RD)348 static bool IsCXXReplaceableType(Sema &S, const CXXRecordDecl *RD) {
349   if (std::optional<ASTContext::CXXRecordDeclRelocationInfo> Info =
350           S.getASTContext().getRelocationInfoForCXXRecord(RD))
351     return Info->IsReplaceable;
352   ASTContext::CXXRecordDeclRelocationInfo Info =
353       S.CheckCXX2CRelocatableAndReplaceable(RD);
354   S.getASTContext().setRelocationInfoForCXXRecord(RD, Info);
355   return Info.IsReplaceable;
356 }
357 
IsCXXReplaceableType(QualType Type)358 bool Sema::IsCXXReplaceableType(QualType Type) {
359   if (Type.isConstQualified() || Type.isVolatileQualified())
360     return false;
361 
362   if (Type->isVariableArrayType())
363     return false;
364 
365   QualType BaseElementType =
366       getASTContext().getBaseElementType(Type.getUnqualifiedType());
367   if (BaseElementType->isIncompleteType())
368     return false;
369   if (BaseElementType->isScalarType())
370     return true;
371   if (const auto *RD = BaseElementType->getAsCXXRecordDecl())
372     return ::IsCXXReplaceableType(*this, RD);
373   return false;
374 }
375 
376 /// Checks that type T is not a VLA.
377 ///
378 /// @returns @c true if @p T is VLA and a diagnostic was emitted,
379 /// @c false otherwise.
DiagnoseVLAInCXXTypeTrait(Sema & S,const TypeSourceInfo * T,clang::tok::TokenKind TypeTraitID)380 static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
381                                       clang::tok::TokenKind TypeTraitID) {
382   if (!T->getType()->isVariableArrayType())
383     return false;
384 
385   S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_vla_unsupported)
386       << 1 << TypeTraitID;
387   return true;
388 }
389 
390 /// Checks that type T is not an atomic type (_Atomic).
391 ///
392 /// @returns @c true if @p T is VLA and a diagnostic was emitted,
393 /// @c false otherwise.
DiagnoseAtomicInCXXTypeTrait(Sema & S,const TypeSourceInfo * T,clang::tok::TokenKind TypeTraitID)394 static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
395                                          clang::tok::TokenKind TypeTraitID) {
396   if (!T->getType()->isAtomicType())
397     return false;
398 
399   S.Diag(T->getTypeLoc().getBeginLoc(), diag::err_atomic_unsupported)
400       << TypeTraitID;
401   return true;
402 }
403 
404 /// Check the completeness of a type in a unary type trait.
405 ///
406 /// If the particular type trait requires a complete type, tries to complete
407 /// it. If completing the type fails, a diagnostic is emitted and false
408 /// returned. If completing the type succeeds or no completion was required,
409 /// returns true.
CheckUnaryTypeTraitTypeCompleteness(Sema & S,TypeTrait UTT,SourceLocation Loc,QualType ArgTy)410 static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
411                                                 SourceLocation Loc,
412                                                 QualType ArgTy) {
413   // C++0x [meta.unary.prop]p3:
414   //   For all of the class templates X declared in this Clause, instantiating
415   //   that template with a template argument that is a class template
416   //   specialization may result in the implicit instantiation of the template
417   //   argument if and only if the semantics of X require that the argument
418   //   must be a complete type.
419   // We apply this rule to all the type trait expressions used to implement
420   // these class templates. We also try to follow any GCC documented behavior
421   // in these expressions to ensure portability of standard libraries.
422   switch (UTT) {
423   default:
424     llvm_unreachable("not a UTT");
425     // is_complete_type somewhat obviously cannot require a complete type.
426   case UTT_IsCompleteType:
427     // Fall-through
428 
429     // These traits are modeled on the type predicates in C++0x
430     // [meta.unary.cat] and [meta.unary.comp]. They are not specified as
431     // requiring a complete type, as whether or not they return true cannot be
432     // impacted by the completeness of the type.
433   case UTT_IsVoid:
434   case UTT_IsIntegral:
435   case UTT_IsFloatingPoint:
436   case UTT_IsArray:
437   case UTT_IsBoundedArray:
438   case UTT_IsPointer:
439   case UTT_IsLvalueReference:
440   case UTT_IsRvalueReference:
441   case UTT_IsMemberFunctionPointer:
442   case UTT_IsMemberObjectPointer:
443   case UTT_IsEnum:
444   case UTT_IsScopedEnum:
445   case UTT_IsUnion:
446   case UTT_IsClass:
447   case UTT_IsFunction:
448   case UTT_IsReference:
449   case UTT_IsArithmetic:
450   case UTT_IsFundamental:
451   case UTT_IsObject:
452   case UTT_IsScalar:
453   case UTT_IsCompound:
454   case UTT_IsMemberPointer:
455   case UTT_IsTypedResourceElementCompatible:
456     // Fall-through
457 
458     // These traits are modeled on type predicates in C++0x [meta.unary.prop]
459     // which requires some of its traits to have the complete type. However,
460     // the completeness of the type cannot impact these traits' semantics, and
461     // so they don't require it. This matches the comments on these traits in
462     // Table 49.
463   case UTT_IsConst:
464   case UTT_IsVolatile:
465   case UTT_IsSigned:
466   case UTT_IsUnboundedArray:
467   case UTT_IsUnsigned:
468 
469     // This type trait always returns false, checking the type is moot.
470   case UTT_IsInterfaceClass:
471     return true;
472 
473     // We diagnose incomplete class types later.
474   case UTT_StructuredBindingSize:
475     return true;
476 
477     // C++14 [meta.unary.prop]:
478     //   If T is a non-union class type, T shall be a complete type.
479   case UTT_IsEmpty:
480   case UTT_IsPolymorphic:
481   case UTT_IsAbstract:
482     if (const auto *RD = ArgTy->getAsCXXRecordDecl())
483       if (!RD->isUnion())
484         return !S.RequireCompleteType(
485             Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
486     return true;
487 
488     // C++14 [meta.unary.prop]:
489     //   If T is a class type, T shall be a complete type.
490   case UTT_IsFinal:
491   case UTT_IsSealed:
492     if (ArgTy->getAsCXXRecordDecl())
493       return !S.RequireCompleteType(
494           Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
495     return true;
496 
497     // LWG3823: T shall be an array type, a complete type, or cv void.
498   case UTT_IsAggregate:
499   case UTT_IsImplicitLifetime:
500     if (ArgTy->isArrayType() || ArgTy->isVoidType())
501       return true;
502 
503     return !S.RequireCompleteType(
504         Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
505 
506     // has_unique_object_representations<T>
507     // remove_all_extents_t<T> shall be a complete type or cv void (LWG4113).
508   case UTT_HasUniqueObjectRepresentations:
509     ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
510     if (ArgTy->isVoidType())
511       return true;
512     return !S.RequireCompleteType(
513         Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
514 
515     // C++1z [meta.unary.prop]:
516     //   remove_all_extents_t<T> shall be a complete type or cv void.
517   case UTT_IsTrivial:
518   case UTT_IsTriviallyCopyable:
519   case UTT_IsStandardLayout:
520   case UTT_IsPOD:
521   case UTT_IsLiteral:
522   case UTT_IsBitwiseCloneable:
523   // By analogy, is_trivially_relocatable and is_trivially_equality_comparable
524   // impose the same constraints.
525   case UTT_IsTriviallyRelocatable:
526   case UTT_IsTriviallyEqualityComparable:
527   case UTT_IsCppTriviallyRelocatable:
528   case UTT_IsReplaceable:
529   case UTT_CanPassInRegs:
530   // Per the GCC type traits documentation, T shall be a complete type, cv void,
531   // or an array of unknown bound. But GCC actually imposes the same constraints
532   // as above.
533   case UTT_HasNothrowAssign:
534   case UTT_HasNothrowMoveAssign:
535   case UTT_HasNothrowConstructor:
536   case UTT_HasNothrowCopy:
537   case UTT_HasTrivialAssign:
538   case UTT_HasTrivialMoveAssign:
539   case UTT_HasTrivialDefaultConstructor:
540   case UTT_HasTrivialMoveConstructor:
541   case UTT_HasTrivialCopy:
542   case UTT_HasTrivialDestructor:
543   case UTT_HasVirtualDestructor:
544     ArgTy = QualType(ArgTy->getBaseElementTypeUnsafe(), 0);
545     [[fallthrough]];
546   // C++1z [meta.unary.prop]:
547   //   T shall be a complete type, cv void, or an array of unknown bound.
548   case UTT_IsDestructible:
549   case UTT_IsNothrowDestructible:
550   case UTT_IsTriviallyDestructible:
551   case UTT_IsIntangibleType:
552     if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
553       return true;
554 
555     return !S.RequireCompleteType(
556         Loc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr);
557   }
558 }
559 
HasNoThrowOperator(const RecordType * RT,OverloadedOperatorKind Op,Sema & Self,SourceLocation KeyLoc,ASTContext & C,bool (CXXRecordDecl::* HasTrivial)()const,bool (CXXRecordDecl::* HasNonTrivial)()const,bool (CXXMethodDecl::* IsDesiredOp)()const)560 static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
561                                Sema &Self, SourceLocation KeyLoc, ASTContext &C,
562                                bool (CXXRecordDecl::*HasTrivial)() const,
563                                bool (CXXRecordDecl::*HasNonTrivial)() const,
564                                bool (CXXMethodDecl::*IsDesiredOp)() const) {
565   CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
566   if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
567     return true;
568 
569   DeclarationName Name = C.DeclarationNames.getCXXOperatorName(Op);
570   DeclarationNameInfo NameInfo(Name, KeyLoc);
571   LookupResult Res(Self, NameInfo, Sema::LookupOrdinaryName);
572   if (Self.LookupQualifiedName(Res, RD)) {
573     bool FoundOperator = false;
574     Res.suppressDiagnostics();
575     for (LookupResult::iterator Op = Res.begin(), OpEnd = Res.end();
576          Op != OpEnd; ++Op) {
577       if (isa<FunctionTemplateDecl>(*Op))
578         continue;
579 
580       CXXMethodDecl *Operator = cast<CXXMethodDecl>(*Op);
581       if ((Operator->*IsDesiredOp)()) {
582         FoundOperator = true;
583         auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
584         CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
585         if (!CPT || !CPT->isNothrow())
586           return false;
587       }
588     }
589     return FoundOperator;
590   }
591   return false;
592 }
593 
HasNonDeletedDefaultedEqualityComparison(Sema & S,const CXXRecordDecl * Decl,SourceLocation KeyLoc)594 static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
595                                                      const CXXRecordDecl *Decl,
596                                                      SourceLocation KeyLoc) {
597   if (Decl->isUnion())
598     return false;
599   if (Decl->isLambda())
600     return Decl->isCapturelessLambda();
601 
602   {
603     EnterExpressionEvaluationContext UnevaluatedContext(
604         S, Sema::ExpressionEvaluationContext::Unevaluated);
605     Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
606     Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
607 
608     // const ClassT& obj;
609     OpaqueValueExpr Operand(
610         KeyLoc,
611         Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
612         ExprValueKind::VK_LValue);
613     UnresolvedSet<16> Functions;
614     // obj == obj;
615     S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);
616 
617     auto Result = S.CreateOverloadedBinOp(KeyLoc, BinaryOperatorKind::BO_EQ,
618                                           Functions, &Operand, &Operand);
619     if (Result.isInvalid() || SFINAE.hasErrorOccurred())
620       return false;
621 
622     const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
623     if (!CallExpr)
624       return false;
625     const auto *Callee = CallExpr->getDirectCallee();
626     auto ParamT = Callee->getParamDecl(0)->getType();
627     if (!Callee->isDefaulted())
628       return false;
629     if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())
630       return false;
631     if (ParamT.getNonReferenceType()->getUnqualifiedDesugaredType() !=
632         Decl->getTypeForDecl())
633       return false;
634   }
635 
636   return llvm::all_of(Decl->bases(),
637                       [&](const CXXBaseSpecifier &BS) {
638                         if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
639                           return HasNonDeletedDefaultedEqualityComparison(
640                               S, RD, KeyLoc);
641                         return true;
642                       }) &&
643          llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
644            auto Type = FD->getType();
645            if (Type->isArrayType())
646              Type = Type->getBaseElementTypeUnsafe()
647                         ->getCanonicalTypeUnqualified();
648 
649            if (Type->isReferenceType() || Type->isEnumeralType())
650              return false;
651            if (const auto *RD = Type->getAsCXXRecordDecl())
652              return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
653            return true;
654          });
655 }
656 
isTriviallyEqualityComparableType(Sema & S,QualType Type,SourceLocation KeyLoc)657 static bool isTriviallyEqualityComparableType(Sema &S, QualType Type,
658                                               SourceLocation KeyLoc) {
659   QualType CanonicalType = Type.getCanonicalType();
660   if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
661       CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
662     return false;
663 
664   if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
665     if (!HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc))
666       return false;
667   }
668 
669   return S.getASTContext().hasUniqueObjectRepresentations(
670       CanonicalType, /*CheckIfTriviallyCopyable=*/false);
671 }
672 
IsTriviallyRelocatableType(Sema & SemaRef,QualType T)673 static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
674   QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(T);
675 
676   if (BaseElementType->isIncompleteType())
677     return false;
678   if (!BaseElementType->isObjectType())
679     return false;
680 
681   // The deprecated __builtin_is_trivially_relocatable does not have
682   // an equivalent to __builtin_trivially_relocate, so there is no
683   // safe way to use it if there are any address discriminated values.
684   if (SemaRef.getASTContext().containsAddressDiscriminatedPointerAuth(T))
685     return false;
686 
687   if (const auto *RD = BaseElementType->getAsCXXRecordDecl();
688       RD && !RD->isPolymorphic() && SemaRef.IsCXXTriviallyRelocatableType(*RD))
689     return true;
690 
691   if (const auto *RD = BaseElementType->getAsRecordDecl())
692     return RD->canPassInRegisters();
693 
694   if (BaseElementType.isTriviallyCopyableType(SemaRef.getASTContext()))
695     return true;
696 
697   switch (T.isNonTrivialToPrimitiveDestructiveMove()) {
698   case QualType::PCK_Trivial:
699     return !T.isDestructedType();
700   case QualType::PCK_ARCStrong:
701     return true;
702   default:
703     return false;
704   }
705 }
706 
EvaluateUnaryTypeTrait(Sema & Self,TypeTrait UTT,SourceLocation KeyLoc,TypeSourceInfo * TInfo)707 static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
708                                    SourceLocation KeyLoc,
709                                    TypeSourceInfo *TInfo) {
710   QualType T = TInfo->getType();
711   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
712 
713   ASTContext &C = Self.Context;
714   switch (UTT) {
715   default:
716     llvm_unreachable("not a UTT");
717     // Type trait expressions corresponding to the primary type category
718     // predicates in C++0x [meta.unary.cat].
719   case UTT_IsVoid:
720     return T->isVoidType();
721   case UTT_IsIntegral:
722     return T->isIntegralType(C);
723   case UTT_IsFloatingPoint:
724     return T->isFloatingType();
725   case UTT_IsArray:
726     // Zero-sized arrays aren't considered arrays in partial specializations,
727     // so __is_array shouldn't consider them arrays either.
728     if (const auto *CAT = C.getAsConstantArrayType(T))
729       return CAT->getSize() != 0;
730     return T->isArrayType();
731   case UTT_IsBoundedArray:
732     if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_bounded_array))
733       return false;
734     // Zero-sized arrays aren't considered arrays in partial specializations,
735     // so __is_bounded_array shouldn't consider them arrays either.
736     if (const auto *CAT = C.getAsConstantArrayType(T))
737       return CAT->getSize() != 0;
738     return T->isArrayType() && !T->isIncompleteArrayType();
739   case UTT_IsUnboundedArray:
740     if (DiagnoseVLAInCXXTypeTrait(Self, TInfo, tok::kw___is_unbounded_array))
741       return false;
742     return T->isIncompleteArrayType();
743   case UTT_IsPointer:
744     return T->isAnyPointerType();
745   case UTT_IsLvalueReference:
746     return T->isLValueReferenceType();
747   case UTT_IsRvalueReference:
748     return T->isRValueReferenceType();
749   case UTT_IsMemberFunctionPointer:
750     return T->isMemberFunctionPointerType();
751   case UTT_IsMemberObjectPointer:
752     return T->isMemberDataPointerType();
753   case UTT_IsEnum:
754     return T->isEnumeralType();
755   case UTT_IsScopedEnum:
756     return T->isScopedEnumeralType();
757   case UTT_IsUnion:
758     return T->isUnionType();
759   case UTT_IsClass:
760     return T->isClassType() || T->isStructureType() || T->isInterfaceType();
761   case UTT_IsFunction:
762     return T->isFunctionType();
763 
764     // Type trait expressions which correspond to the convenient composition
765     // predicates in C++0x [meta.unary.comp].
766   case UTT_IsReference:
767     return T->isReferenceType();
768   case UTT_IsArithmetic:
769     return T->isArithmeticType() && !T->isEnumeralType();
770   case UTT_IsFundamental:
771     return T->isFundamentalType();
772   case UTT_IsObject:
773     return T->isObjectType();
774   case UTT_IsScalar:
775     // Note: semantic analysis depends on Objective-C lifetime types to be
776     // considered scalar types. However, such types do not actually behave
777     // like scalar types at run time (since they may require retain/release
778     // operations), so we report them as non-scalar.
779     if (T->isObjCLifetimeType()) {
780       switch (T.getObjCLifetime()) {
781       case Qualifiers::OCL_None:
782       case Qualifiers::OCL_ExplicitNone:
783         return true;
784 
785       case Qualifiers::OCL_Strong:
786       case Qualifiers::OCL_Weak:
787       case Qualifiers::OCL_Autoreleasing:
788         return false;
789       }
790     }
791 
792     return T->isScalarType();
793   case UTT_IsCompound:
794     return T->isCompoundType();
795   case UTT_IsMemberPointer:
796     return T->isMemberPointerType();
797 
798     // Type trait expressions which correspond to the type property predicates
799     // in C++0x [meta.unary.prop].
800   case UTT_IsConst:
801     return T.isConstQualified();
802   case UTT_IsVolatile:
803     return T.isVolatileQualified();
804   case UTT_IsTrivial:
805     return T.isTrivialType(C);
806   case UTT_IsTriviallyCopyable:
807     return T.isTriviallyCopyableType(C);
808   case UTT_IsStandardLayout:
809     return T->isStandardLayoutType();
810   case UTT_IsPOD:
811     return T.isPODType(C);
812   case UTT_IsLiteral:
813     return T->isLiteralType(C);
814   case UTT_IsEmpty:
815     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
816       return !RD->isUnion() && RD->isEmpty();
817     return false;
818   case UTT_IsPolymorphic:
819     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
820       return !RD->isUnion() && RD->isPolymorphic();
821     return false;
822   case UTT_IsAbstract:
823     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
824       return !RD->isUnion() && RD->isAbstract();
825     return false;
826   case UTT_IsAggregate:
827     // Report vector extensions and complex types as aggregates because they
828     // support aggregate initialization. GCC mirrors this behavior for vectors
829     // but not _Complex.
830     return T->isAggregateType() || T->isVectorType() || T->isExtVectorType() ||
831            T->isAnyComplexType();
832   // __is_interface_class only returns true when CL is invoked in /CLR mode and
833   // even then only when it is used with the 'interface struct ...' syntax
834   // Clang doesn't support /CLR which makes this type trait moot.
835   case UTT_IsInterfaceClass:
836     return false;
837   case UTT_IsFinal:
838   case UTT_IsSealed:
839     if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
840       return RD->hasAttr<FinalAttr>();
841     return false;
842   case UTT_IsSigned:
843     // Enum types should always return false.
844     // Floating points should always return true.
845     return T->isFloatingType() ||
846            (T->isSignedIntegerType() && !T->isEnumeralType());
847   case UTT_IsUnsigned:
848     // Enum types should always return false.
849     return T->isUnsignedIntegerType() && !T->isEnumeralType();
850 
851     // Type trait expressions which query classes regarding their construction,
852     // destruction, and copying. Rather than being based directly on the
853     // related type predicates in the standard, they are specified by both
854     // GCC[1] and the Embarcadero C++ compiler[2], and Clang implements those
855     // specifications.
856     //
857     //   1: http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
858     //   2:
859     //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
860     //
861     // Note that these builtins do not behave as documented in g++: if a class
862     // has both a trivial and a non-trivial special member of a particular kind,
863     // they return false! For now, we emulate this behavior.
864     // FIXME: This appears to be a g++ bug: more complex cases reveal that it
865     // does not correctly compute triviality in the presence of multiple special
866     // members of the same kind. Revisit this once the g++ bug is fixed.
867   case UTT_HasTrivialDefaultConstructor:
868     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
869     //   If __is_pod (type) is true then the trait is true, else if type is
870     //   a cv class or union type (or array thereof) with a trivial default
871     //   constructor ([class.ctor]) then the trait is true, else it is false.
872     if (T.isPODType(C))
873       return true;
874     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
875       return RD->hasTrivialDefaultConstructor() &&
876              !RD->hasNonTrivialDefaultConstructor();
877     return false;
878   case UTT_HasTrivialMoveConstructor:
879     //  This trait is implemented by MSVC 2012 and needed to parse the
880     //  standard library headers. Specifically this is used as the logic
881     //  behind std::is_trivially_move_constructible (20.9.4.3).
882     if (T.isPODType(C))
883       return true;
884     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
885       return RD->hasTrivialMoveConstructor() &&
886              !RD->hasNonTrivialMoveConstructor();
887     return false;
888   case UTT_HasTrivialCopy:
889     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
890     //   If __is_pod (type) is true or type is a reference type then
891     //   the trait is true, else if type is a cv class or union type
892     //   with a trivial copy constructor ([class.copy]) then the trait
893     //   is true, else it is false.
894     if (T.isPODType(C) || T->isReferenceType())
895       return true;
896     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
897       return RD->hasTrivialCopyConstructor() &&
898              !RD->hasNonTrivialCopyConstructor();
899     return false;
900   case UTT_HasTrivialMoveAssign:
901     //  This trait is implemented by MSVC 2012 and needed to parse the
902     //  standard library headers. Specifically it is used as the logic
903     //  behind std::is_trivially_move_assignable (20.9.4.3)
904     if (T.isPODType(C))
905       return true;
906     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
907       return RD->hasTrivialMoveAssignment() &&
908              !RD->hasNonTrivialMoveAssignment();
909     return false;
910   case UTT_HasTrivialAssign:
911     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
912     //   If type is const qualified or is a reference type then the
913     //   trait is false. Otherwise if __is_pod (type) is true then the
914     //   trait is true, else if type is a cv class or union type with
915     //   a trivial copy assignment ([class.copy]) then the trait is
916     //   true, else it is false.
917     // Note: the const and reference restrictions are interesting,
918     // given that const and reference members don't prevent a class
919     // from having a trivial copy assignment operator (but do cause
920     // errors if the copy assignment operator is actually used, q.v.
921     // [class.copy]p12).
922 
923     if (T.isConstQualified())
924       return false;
925     if (T.isPODType(C))
926       return true;
927     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
928       return RD->hasTrivialCopyAssignment() &&
929              !RD->hasNonTrivialCopyAssignment();
930     return false;
931   case UTT_IsDestructible:
932   case UTT_IsTriviallyDestructible:
933   case UTT_IsNothrowDestructible:
934     // C++14 [meta.unary.prop]:
935     //   For reference types, is_destructible<T>::value is true.
936     if (T->isReferenceType())
937       return true;
938 
939     // Objective-C++ ARC: autorelease types don't require destruction.
940     if (T->isObjCLifetimeType() &&
941         T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
942       return true;
943 
944     // C++14 [meta.unary.prop]:
945     //   For incomplete types and function types, is_destructible<T>::value is
946     //   false.
947     if (T->isIncompleteType() || T->isFunctionType())
948       return false;
949 
950     // A type that requires destruction (via a non-trivial destructor or ARC
951     // lifetime semantics) is not trivially-destructible.
952     if (UTT == UTT_IsTriviallyDestructible && T.isDestructedType())
953       return false;
954 
955     // C++14 [meta.unary.prop]:
956     //   For object types and given U equal to remove_all_extents_t<T>, if the
957     //   expression std::declval<U&>().~U() is well-formed when treated as an
958     //   unevaluated operand (Clause 5), then is_destructible<T>::value is true
959     if (auto *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
960       CXXDestructorDecl *Destructor = Self.LookupDestructor(RD);
961       if (!Destructor)
962         return false;
963       //  C++14 [dcl.fct.def.delete]p2:
964       //    A program that refers to a deleted function implicitly or
965       //    explicitly, other than to declare it, is ill-formed.
966       if (Destructor->isDeleted())
967         return false;
968       if (C.getLangOpts().AccessControl && Destructor->getAccess() != AS_public)
969         return false;
970       if (UTT == UTT_IsNothrowDestructible) {
971         auto *CPT = Destructor->getType()->castAs<FunctionProtoType>();
972         CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
973         if (!CPT || !CPT->isNothrow())
974           return false;
975       }
976     }
977     return true;
978 
979   case UTT_HasTrivialDestructor:
980     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
981     //   If __is_pod (type) is true or type is a reference type
982     //   then the trait is true, else if type is a cv class or union
983     //   type (or array thereof) with a trivial destructor
984     //   ([class.dtor]) then the trait is true, else it is
985     //   false.
986     if (T.isPODType(C) || T->isReferenceType())
987       return true;
988 
989     // Objective-C++ ARC: autorelease types don't require destruction.
990     if (T->isObjCLifetimeType() &&
991         T.getObjCLifetime() == Qualifiers::OCL_Autoreleasing)
992       return true;
993 
994     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl())
995       return RD->hasTrivialDestructor();
996     return false;
997   // TODO: Propagate nothrowness for implicitly declared special members.
998   case UTT_HasNothrowAssign:
999     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1000     //   If type is const qualified or is a reference type then the
1001     //   trait is false. Otherwise if __has_trivial_assign (type)
1002     //   is true then the trait is true, else if type is a cv class
1003     //   or union type with copy assignment operators that are known
1004     //   not to throw an exception then the trait is true, else it is
1005     //   false.
1006     if (C.getBaseElementType(T).isConstQualified())
1007       return false;
1008     if (T->isReferenceType())
1009       return false;
1010     if (T.isPODType(C) || T->isObjCLifetimeType())
1011       return true;
1012 
1013     if (const RecordType *RT = T->getAs<RecordType>())
1014       return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
1015                                 &CXXRecordDecl::hasTrivialCopyAssignment,
1016                                 &CXXRecordDecl::hasNonTrivialCopyAssignment,
1017                                 &CXXMethodDecl::isCopyAssignmentOperator);
1018     return false;
1019   case UTT_HasNothrowMoveAssign:
1020     //  This trait is implemented by MSVC 2012 and needed to parse the
1021     //  standard library headers. Specifically this is used as the logic
1022     //  behind std::is_nothrow_move_assignable (20.9.4.3).
1023     if (T.isPODType(C))
1024       return true;
1025 
1026     if (const RecordType *RT = C.getBaseElementType(T)->getAs<RecordType>())
1027       return HasNoThrowOperator(RT, OO_Equal, Self, KeyLoc, C,
1028                                 &CXXRecordDecl::hasTrivialMoveAssignment,
1029                                 &CXXRecordDecl::hasNonTrivialMoveAssignment,
1030                                 &CXXMethodDecl::isMoveAssignmentOperator);
1031     return false;
1032   case UTT_HasNothrowCopy:
1033     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1034     //   If __has_trivial_copy (type) is true then the trait is true, else
1035     //   if type is a cv class or union type with copy constructors that are
1036     //   known not to throw an exception then the trait is true, else it is
1037     //   false.
1038     if (T.isPODType(C) || T->isReferenceType() || T->isObjCLifetimeType())
1039       return true;
1040     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) {
1041       if (RD->hasTrivialCopyConstructor() &&
1042           !RD->hasNonTrivialCopyConstructor())
1043         return true;
1044 
1045       bool FoundConstructor = false;
1046       unsigned FoundTQs;
1047       for (const auto *ND : Self.LookupConstructors(RD)) {
1048         // A template constructor is never a copy constructor.
1049         // FIXME: However, it may actually be selected at the actual overload
1050         // resolution point.
1051         if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1052           continue;
1053         // UsingDecl itself is not a constructor
1054         if (isa<UsingDecl>(ND))
1055           continue;
1056         auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1057         if (Constructor->isCopyConstructor(FoundTQs)) {
1058           FoundConstructor = true;
1059           auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1060           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1061           if (!CPT)
1062             return false;
1063           // TODO: check whether evaluating default arguments can throw.
1064           // For now, we'll be conservative and assume that they can throw.
1065           if (!CPT->isNothrow() || CPT->getNumParams() > 1)
1066             return false;
1067         }
1068       }
1069 
1070       return FoundConstructor;
1071     }
1072     return false;
1073   case UTT_HasNothrowConstructor:
1074     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
1075     //   If __has_trivial_constructor (type) is true then the trait is
1076     //   true, else if type is a cv class or union type (or array
1077     //   thereof) with a default constructor that is known not to
1078     //   throw an exception then the trait is true, else it is false.
1079     if (T.isPODType(C) || T->isObjCLifetimeType())
1080       return true;
1081     if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1082       if (RD->hasTrivialDefaultConstructor() &&
1083           !RD->hasNonTrivialDefaultConstructor())
1084         return true;
1085 
1086       bool FoundConstructor = false;
1087       for (const auto *ND : Self.LookupConstructors(RD)) {
1088         // FIXME: In C++0x, a constructor template can be a default constructor.
1089         if (isa<FunctionTemplateDecl>(ND->getUnderlyingDecl()))
1090           continue;
1091         // UsingDecl itself is not a constructor
1092         if (isa<UsingDecl>(ND))
1093           continue;
1094         auto *Constructor = cast<CXXConstructorDecl>(ND->getUnderlyingDecl());
1095         if (Constructor->isDefaultConstructor()) {
1096           FoundConstructor = true;
1097           auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1098           CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
1099           if (!CPT)
1100             return false;
1101           // FIXME: check whether evaluating default arguments can throw.
1102           // For now, we'll be conservative and assume that they can throw.
1103           if (!CPT->isNothrow() || CPT->getNumParams() > 0)
1104             return false;
1105         }
1106       }
1107       return FoundConstructor;
1108     }
1109     return false;
1110   case UTT_HasVirtualDestructor:
1111     // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
1112     //   If type is a class type with a virtual destructor ([class.dtor])
1113     //   then the trait is true, else it is false.
1114     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
1115       if (CXXDestructorDecl *Destructor = Self.LookupDestructor(RD))
1116         return Destructor->isVirtual();
1117     return false;
1118 
1119     // These type trait expressions are modeled on the specifications for the
1120     // Embarcadero C++0x type trait functions:
1121     //   http://docwiki.embarcadero.com/RADStudio/XE/en/Type_Trait_Functions_(C%2B%2B0x)_Index
1122   case UTT_IsCompleteType:
1123     // http://docwiki.embarcadero.com/RADStudio/XE/en/Is_complete_type_(typename_T_):
1124     //   Returns True if and only if T is a complete type at the point of the
1125     //   function call.
1126     return !T->isIncompleteType();
1127   case UTT_HasUniqueObjectRepresentations:
1128     return C.hasUniqueObjectRepresentations(T);
1129   case UTT_IsTriviallyRelocatable:
1130     return IsTriviallyRelocatableType(Self, T);
1131   case UTT_IsBitwiseCloneable:
1132     return T.isBitwiseCloneableType(C);
1133   case UTT_IsCppTriviallyRelocatable:
1134     return Self.IsCXXTriviallyRelocatableType(T);
1135   case UTT_IsReplaceable:
1136     return Self.IsCXXReplaceableType(T);
1137   case UTT_CanPassInRegs:
1138     if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1139       return RD->canPassInRegisters();
1140     Self.Diag(KeyLoc, diag::err_builtin_pass_in_regs_non_class) << T;
1141     return false;
1142   case UTT_IsTriviallyEqualityComparable:
1143     return isTriviallyEqualityComparableType(Self, T, KeyLoc);
1144   case UTT_IsImplicitLifetime: {
1145     DiagnoseVLAInCXXTypeTrait(Self, TInfo,
1146                               tok::kw___builtin_is_implicit_lifetime);
1147     DiagnoseAtomicInCXXTypeTrait(Self, TInfo,
1148                                  tok::kw___builtin_is_implicit_lifetime);
1149 
1150     // [basic.types.general] p9
1151     // Scalar types, implicit-lifetime class types ([class.prop]),
1152     // array types, and cv-qualified versions of these types
1153     // are collectively called implicit-lifetime types.
1154     QualType UnqualT = T->getCanonicalTypeUnqualified();
1155     if (UnqualT->isScalarType())
1156       return true;
1157     if (UnqualT->isArrayType() || UnqualT->isVectorType())
1158       return true;
1159     const CXXRecordDecl *RD = UnqualT->getAsCXXRecordDecl();
1160     if (!RD)
1161       return false;
1162 
1163     // [class.prop] p9
1164     // A class S is an implicit-lifetime class if
1165     //   - it is an aggregate whose destructor is not user-provided or
1166     //   - it has at least one trivial eligible constructor and a trivial,
1167     //     non-deleted destructor.
1168     const CXXDestructorDecl *Dtor = RD->getDestructor();
1169     if (UnqualT->isAggregateType())
1170       if (Dtor && !Dtor->isUserProvided())
1171         return true;
1172     if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted()))
1173       if (RD->hasTrivialDefaultConstructor() ||
1174           RD->hasTrivialCopyConstructor() || RD->hasTrivialMoveConstructor())
1175         return true;
1176     return false;
1177   }
1178   case UTT_IsIntangibleType:
1179     assert(Self.getLangOpts().HLSL && "intangible types are HLSL-only feature");
1180     if (!T->isVoidType() && !T->isIncompleteArrayType())
1181       if (Self.RequireCompleteType(TInfo->getTypeLoc().getBeginLoc(), T,
1182                                    diag::err_incomplete_type))
1183         return false;
1184     if (DiagnoseVLAInCXXTypeTrait(Self, TInfo,
1185                                   tok::kw___builtin_hlsl_is_intangible))
1186       return false;
1187     return T->isHLSLIntangibleType();
1188 
1189   case UTT_IsTypedResourceElementCompatible:
1190     assert(Self.getLangOpts().HLSL &&
1191            "typed resource element compatible types are an HLSL-only feature");
1192     if (T->isIncompleteType())
1193       return false;
1194 
1195     return Self.HLSL().IsTypedResourceElementCompatible(T);
1196   }
1197 }
1198 
1199 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1200                                     const TypeSourceInfo *Lhs,
1201                                     const TypeSourceInfo *Rhs,
1202                                     SourceLocation KeyLoc);
1203 
CheckConvertibilityForTypeTraits(Sema & Self,const TypeSourceInfo * Lhs,const TypeSourceInfo * Rhs,SourceLocation KeyLoc,llvm::BumpPtrAllocator & OpaqueExprAllocator)1204 static ExprResult CheckConvertibilityForTypeTraits(
1205     Sema &Self, const TypeSourceInfo *Lhs, const TypeSourceInfo *Rhs,
1206     SourceLocation KeyLoc, llvm::BumpPtrAllocator &OpaqueExprAllocator) {
1207 
1208   QualType LhsT = Lhs->getType();
1209   QualType RhsT = Rhs->getType();
1210 
1211   // C++0x [meta.rel]p4:
1212   //   Given the following function prototype:
1213   //
1214   //     template <class T>
1215   //       typename add_rvalue_reference<T>::type create();
1216   //
1217   //   the predicate condition for a template specialization
1218   //   is_convertible<From, To> shall be satisfied if and only if
1219   //   the return expression in the following code would be
1220   //   well-formed, including any implicit conversions to the return
1221   //   type of the function:
1222   //
1223   //     To test() {
1224   //       return create<From>();
1225   //     }
1226   //
1227   //   Access checking is performed as if in a context unrelated to To and
1228   //   From. Only the validity of the immediate context of the expression
1229   //   of the return-statement (including conversions to the return type)
1230   //   is considered.
1231   //
1232   // We model the initialization as a copy-initialization of a temporary
1233   // of the appropriate type, which for this expression is identical to the
1234   // return statement (since NRVO doesn't apply).
1235 
1236   // Functions aren't allowed to return function or array types.
1237   if (RhsT->isFunctionType() || RhsT->isArrayType())
1238     return ExprError();
1239 
1240   // A function definition requires a complete, non-abstract return type.
1241   if (!Self.isCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT) ||
1242       Self.isAbstractType(Rhs->getTypeLoc().getBeginLoc(), RhsT))
1243     return ExprError();
1244 
1245   // Compute the result of add_rvalue_reference.
1246   if (LhsT->isObjectType() || LhsT->isFunctionType())
1247     LhsT = Self.Context.getRValueReferenceType(LhsT);
1248 
1249   // Build a fake source and destination for initialization.
1250   InitializedEntity To(InitializedEntity::InitializeTemporary(RhsT));
1251   Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1252       OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
1253                       Expr::getValueKindForType(LhsT));
1254   InitializationKind Kind =
1255       InitializationKind::CreateCopy(KeyLoc, SourceLocation());
1256 
1257   // Perform the initialization in an unevaluated context within a SFINAE
1258   // trap at translation unit scope.
1259   EnterExpressionEvaluationContext Unevaluated(
1260       Self, Sema::ExpressionEvaluationContext::Unevaluated);
1261   Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1262   Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1263   InitializationSequence Init(Self, To, Kind, From);
1264   if (Init.Failed())
1265     return ExprError();
1266 
1267   ExprResult Result = Init.Perform(Self, To, Kind, From);
1268   if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1269     return ExprError();
1270 
1271   return Result;
1272 }
1273 
EvaluateSizeTTypeTrait(Sema & S,TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc,bool IsDependent)1274 static APValue EvaluateSizeTTypeTrait(Sema &S, TypeTrait Kind,
1275                                       SourceLocation KWLoc,
1276                                       ArrayRef<TypeSourceInfo *> Args,
1277                                       SourceLocation RParenLoc,
1278                                       bool IsDependent) {
1279   if (IsDependent)
1280     return APValue();
1281 
1282   switch (Kind) {
1283   case TypeTrait::UTT_StructuredBindingSize: {
1284     QualType T = Args[0]->getType();
1285     SourceRange ArgRange = Args[0]->getTypeLoc().getSourceRange();
1286     UnsignedOrNone Size =
1287         S.GetDecompositionElementCount(T, ArgRange.getBegin());
1288     if (!Size) {
1289       S.Diag(KWLoc, diag::err_arg_is_not_destructurable) << T << ArgRange;
1290       return APValue();
1291     }
1292     return APValue(
1293         S.getASTContext().MakeIntValue(*Size, S.getASTContext().getSizeType()));
1294     break;
1295   }
1296   default:
1297     llvm_unreachable("Not a SizeT type trait");
1298   }
1299 }
1300 
EvaluateBooleanTypeTrait(Sema & S,TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc,bool IsDependent)1301 static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
1302                                      SourceLocation KWLoc,
1303                                      ArrayRef<TypeSourceInfo *> Args,
1304                                      SourceLocation RParenLoc,
1305                                      bool IsDependent) {
1306   if (IsDependent)
1307     return false;
1308 
1309   if (Kind <= UTT_Last)
1310     return EvaluateUnaryTypeTrait(S, Kind, KWLoc, Args[0]);
1311 
1312   // Evaluate ReferenceBindsToTemporary and ReferenceConstructsFromTemporary
1313   // alongside the IsConstructible traits to avoid duplication.
1314   if (Kind <= BTT_Last && Kind != BTT_ReferenceBindsToTemporary &&
1315       Kind != BTT_ReferenceConstructsFromTemporary &&
1316       Kind != BTT_ReferenceConvertsFromTemporary)
1317     return EvaluateBinaryTypeTrait(S, Kind, Args[0], Args[1], RParenLoc);
1318 
1319   switch (Kind) {
1320   case clang::BTT_ReferenceBindsToTemporary:
1321   case clang::BTT_ReferenceConstructsFromTemporary:
1322   case clang::BTT_ReferenceConvertsFromTemporary:
1323   case clang::TT_IsConstructible:
1324   case clang::TT_IsNothrowConstructible:
1325   case clang::TT_IsTriviallyConstructible: {
1326     // C++11 [meta.unary.prop]:
1327     //   is_trivially_constructible is defined as:
1328     //
1329     //     is_constructible<T, Args...>::value is true and the variable
1330     //     definition for is_constructible, as defined below, is known to call
1331     //     no operation that is not trivial.
1332     //
1333     //   The predicate condition for a template specialization
1334     //   is_constructible<T, Args...> shall be satisfied if and only if the
1335     //   following variable definition would be well-formed for some invented
1336     //   variable t:
1337     //
1338     //     T t(create<Args>()...);
1339     assert(!Args.empty());
1340 
1341     // Precondition: T and all types in the parameter pack Args shall be
1342     // complete types, (possibly cv-qualified) void, or arrays of
1343     // unknown bound.
1344     for (const auto *TSI : Args) {
1345       QualType ArgTy = TSI->getType();
1346       if (ArgTy->isVoidType() || ArgTy->isIncompleteArrayType())
1347         continue;
1348 
1349       if (S.RequireCompleteType(
1350               KWLoc, ArgTy, diag::err_incomplete_type_used_in_type_trait_expr))
1351         return false;
1352     }
1353 
1354     // Make sure the first argument is not incomplete nor a function type.
1355     QualType T = Args[0]->getType();
1356     if (T->isIncompleteType() || T->isFunctionType())
1357       return false;
1358 
1359     // Make sure the first argument is not an abstract type.
1360     CXXRecordDecl *RD = T->getAsCXXRecordDecl();
1361     if (RD && RD->isAbstract())
1362       return false;
1363 
1364     // LWG3819: For reference_meows_from_temporary traits, && is not added to
1365     // the source object type.
1366     // Otherwise, compute the result of add_rvalue_reference_t.
1367     bool UseRawObjectType =
1368         Kind == clang::BTT_ReferenceBindsToTemporary ||
1369         Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1370         Kind == clang::BTT_ReferenceConvertsFromTemporary;
1371 
1372     llvm::BumpPtrAllocator OpaqueExprAllocator;
1373     SmallVector<Expr *, 2> ArgExprs;
1374     ArgExprs.reserve(Args.size() - 1);
1375     for (unsigned I = 1, N = Args.size(); I != N; ++I) {
1376       QualType ArgTy = Args[I]->getType();
1377       if ((ArgTy->isObjectType() && !UseRawObjectType) ||
1378           ArgTy->isFunctionType())
1379         ArgTy = S.Context.getRValueReferenceType(ArgTy);
1380       ArgExprs.push_back(
1381           new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1382               OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1383                               ArgTy.getNonLValueExprType(S.Context),
1384                               Expr::getValueKindForType(ArgTy)));
1385     }
1386 
1387     // Perform the initialization in an unevaluated context within a SFINAE
1388     // trap at translation unit scope.
1389     EnterExpressionEvaluationContext Unevaluated(
1390         S, Sema::ExpressionEvaluationContext::Unevaluated);
1391     Sema::SFINAETrap SFINAE(S, /*ForValidityCheck=*/true);
1392     Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
1393     InitializedEntity To(
1394         InitializedEntity::InitializeTemporary(S.Context, Args[0]));
1395     InitializationKind InitKind(
1396         Kind == clang::BTT_ReferenceConvertsFromTemporary
1397             ? InitializationKind::CreateCopy(KWLoc, KWLoc)
1398             : InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
1399     InitializationSequence Init(S, To, InitKind, ArgExprs);
1400     if (Init.Failed())
1401       return false;
1402 
1403     ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
1404     if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1405       return false;
1406 
1407     if (Kind == clang::TT_IsConstructible)
1408       return true;
1409 
1410     if (Kind == clang::BTT_ReferenceBindsToTemporary ||
1411         Kind == clang::BTT_ReferenceConstructsFromTemporary ||
1412         Kind == clang::BTT_ReferenceConvertsFromTemporary) {
1413       if (!T->isReferenceType())
1414         return false;
1415 
1416       // A function reference never binds to a temporary object.
1417       if (T.getNonReferenceType()->isFunctionType())
1418         return false;
1419 
1420       if (!Init.isDirectReferenceBinding())
1421         return true;
1422 
1423       if (Kind == clang::BTT_ReferenceBindsToTemporary)
1424         return false;
1425 
1426       QualType U = Args[1]->getType();
1427       if (U->isReferenceType())
1428         return false;
1429 
1430       TypeSourceInfo *TPtr = S.Context.CreateTypeSourceInfo(
1431           S.Context.getPointerType(T.getNonReferenceType()));
1432       TypeSourceInfo *UPtr = S.Context.CreateTypeSourceInfo(
1433           S.Context.getPointerType(U.getNonReferenceType()));
1434       return !CheckConvertibilityForTypeTraits(S, UPtr, TPtr, RParenLoc,
1435                                                OpaqueExprAllocator)
1436                   .isInvalid();
1437     }
1438 
1439     if (Kind == clang::TT_IsNothrowConstructible)
1440       return S.canThrow(Result.get()) == CT_Cannot;
1441 
1442     if (Kind == clang::TT_IsTriviallyConstructible) {
1443       // Under Objective-C ARC and Weak, if the destination has non-trivial
1444       // Objective-C lifetime, this is a non-trivial construction.
1445       if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
1446         return false;
1447 
1448       // The initialization succeeded; now make sure there are no non-trivial
1449       // calls.
1450       return !Result.get()->hasNonTrivialCall(S.Context);
1451     }
1452 
1453     llvm_unreachable("unhandled type trait");
1454     return false;
1455   }
1456   default:
1457     llvm_unreachable("not a TT");
1458   }
1459 
1460   return false;
1461 }
1462 
1463 namespace {
DiagnoseBuiltinDeprecation(Sema & S,TypeTrait Kind,SourceLocation KWLoc)1464 void DiagnoseBuiltinDeprecation(Sema &S, TypeTrait Kind, SourceLocation KWLoc) {
1465   TypeTrait Replacement;
1466   switch (Kind) {
1467   case UTT_HasNothrowAssign:
1468   case UTT_HasNothrowMoveAssign:
1469     Replacement = BTT_IsNothrowAssignable;
1470     break;
1471   case UTT_HasNothrowCopy:
1472   case UTT_HasNothrowConstructor:
1473     Replacement = TT_IsNothrowConstructible;
1474     break;
1475   case UTT_HasTrivialAssign:
1476   case UTT_HasTrivialMoveAssign:
1477     Replacement = BTT_IsTriviallyAssignable;
1478     break;
1479   case UTT_HasTrivialCopy:
1480     Replacement = UTT_IsTriviallyCopyable;
1481     break;
1482   case UTT_HasTrivialDefaultConstructor:
1483   case UTT_HasTrivialMoveConstructor:
1484     Replacement = TT_IsTriviallyConstructible;
1485     break;
1486   case UTT_HasTrivialDestructor:
1487     Replacement = UTT_IsTriviallyDestructible;
1488     break;
1489   case UTT_IsTriviallyRelocatable:
1490     Replacement = clang::UTT_IsCppTriviallyRelocatable;
1491     break;
1492   case BTT_ReferenceBindsToTemporary:
1493     Replacement = clang::BTT_ReferenceConstructsFromTemporary;
1494     break;
1495   default:
1496     return;
1497   }
1498   S.Diag(KWLoc, diag::warn_deprecated_builtin)
1499       << getTraitSpelling(Kind) << getTraitSpelling(Replacement);
1500 }
1501 } // namespace
1502 
CheckTypeTraitArity(unsigned Arity,SourceLocation Loc,size_t N)1503 bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1504   if (Arity && N != Arity) {
1505     Diag(Loc, diag::err_type_trait_arity)
1506         << Arity << 0 << (Arity > 1) << (int)N << SourceRange(Loc);
1507     return false;
1508   }
1509 
1510   if (!Arity && N == 0) {
1511     Diag(Loc, diag::err_type_trait_arity)
1512         << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1513     return false;
1514   }
1515   return true;
1516 }
1517 
1518 enum class TypeTraitReturnType {
1519   Bool,
1520   SizeT,
1521 };
1522 
GetReturnType(TypeTrait Kind)1523 static TypeTraitReturnType GetReturnType(TypeTrait Kind) {
1524   if (Kind == TypeTrait::UTT_StructuredBindingSize)
1525     return TypeTraitReturnType::SizeT;
1526   return TypeTraitReturnType::Bool;
1527 }
1528 
BuildTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<TypeSourceInfo * > Args,SourceLocation RParenLoc)1529 ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
1530                                 ArrayRef<TypeSourceInfo *> Args,
1531                                 SourceLocation RParenLoc) {
1532   if (!CheckTypeTraitArity(getTypeTraitArity(Kind), KWLoc, Args.size()))
1533     return ExprError();
1534 
1535   if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(
1536                               *this, Kind, KWLoc, Args[0]->getType()))
1537     return ExprError();
1538 
1539   DiagnoseBuiltinDeprecation(*this, Kind, KWLoc);
1540 
1541   bool Dependent = false;
1542   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1543     if (Args[I]->getType()->isDependentType()) {
1544       Dependent = true;
1545       break;
1546     }
1547   }
1548 
1549   switch (GetReturnType(Kind)) {
1550   case TypeTraitReturnType::Bool: {
1551     bool Result = EvaluateBooleanTypeTrait(*this, Kind, KWLoc, Args, RParenLoc,
1552                                            Dependent);
1553     return TypeTraitExpr::Create(Context, Context.getLogicalOperationType(),
1554                                  KWLoc, Kind, Args, RParenLoc, Result);
1555   }
1556   case TypeTraitReturnType::SizeT: {
1557     APValue Result =
1558         EvaluateSizeTTypeTrait(*this, Kind, KWLoc, Args, RParenLoc, Dependent);
1559     return TypeTraitExpr::Create(Context, Context.getSizeType(), KWLoc, Kind,
1560                                  Args, RParenLoc, Result);
1561   }
1562   }
1563   llvm_unreachable("unhandled type trait return type");
1564 }
1565 
ActOnTypeTrait(TypeTrait Kind,SourceLocation KWLoc,ArrayRef<ParsedType> Args,SourceLocation RParenLoc)1566 ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
1567                                 ArrayRef<ParsedType> Args,
1568                                 SourceLocation RParenLoc) {
1569   SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
1570   ConvertedArgs.reserve(Args.size());
1571 
1572   for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1573     TypeSourceInfo *TInfo;
1574     QualType T = GetTypeFromParser(Args[I], &TInfo);
1575     if (!TInfo)
1576       TInfo = Context.getTrivialTypeSourceInfo(T, KWLoc);
1577 
1578     ConvertedArgs.push_back(TInfo);
1579   }
1580 
1581   return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc);
1582 }
1583 
BuiltinIsBaseOf(SourceLocation RhsTLoc,QualType LhsT,QualType RhsT)1584 bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,
1585                            QualType RhsT) {
1586   // C++0x [meta.rel]p2
1587   // Base is a base class of Derived without regard to cv-qualifiers or
1588   // Base and Derived are not unions and name the same class type without
1589   // regard to cv-qualifiers.
1590 
1591   const RecordType *lhsRecord = LhsT->getAs<RecordType>();
1592   const RecordType *rhsRecord = RhsT->getAs<RecordType>();
1593   if (!rhsRecord || !lhsRecord) {
1594     const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
1595     const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
1596     if (!LHSObjTy || !RHSObjTy)
1597       return false;
1598 
1599     ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
1600     ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
1601     if (!BaseInterface || !DerivedInterface)
1602       return false;
1603 
1604     if (RequireCompleteType(RhsTLoc, RhsT,
1605                             diag::err_incomplete_type_used_in_type_trait_expr))
1606       return false;
1607 
1608     return BaseInterface->isSuperClassOf(DerivedInterface);
1609   }
1610 
1611   assert(Context.hasSameUnqualifiedType(LhsT, RhsT) ==
1612          (lhsRecord == rhsRecord));
1613 
1614   // Unions are never base classes, and never have base classes.
1615   // It doesn't matter if they are complete or not. See PR#41843
1616   if (lhsRecord && lhsRecord->getDecl()->isUnion())
1617     return false;
1618   if (rhsRecord && rhsRecord->getDecl()->isUnion())
1619     return false;
1620 
1621   if (lhsRecord == rhsRecord)
1622     return true;
1623 
1624   // C++0x [meta.rel]p2:
1625   //   If Base and Derived are class types and are different types
1626   //   (ignoring possible cv-qualifiers) then Derived shall be a
1627   //   complete type.
1628   if (RequireCompleteType(RhsTLoc, RhsT,
1629                           diag::err_incomplete_type_used_in_type_trait_expr))
1630     return false;
1631 
1632   return cast<CXXRecordDecl>(rhsRecord->getDecl())
1633       ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
1634 }
1635 
EvaluateBinaryTypeTrait(Sema & Self,TypeTrait BTT,const TypeSourceInfo * Lhs,const TypeSourceInfo * Rhs,SourceLocation KeyLoc)1636 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1637                                     const TypeSourceInfo *Lhs,
1638                                     const TypeSourceInfo *Rhs,
1639                                     SourceLocation KeyLoc) {
1640   QualType LhsT = Lhs->getType();
1641   QualType RhsT = Rhs->getType();
1642 
1643   assert(!LhsT->isDependentType() && !RhsT->isDependentType() &&
1644          "Cannot evaluate traits of dependent types");
1645 
1646   switch (BTT) {
1647   case BTT_IsBaseOf:
1648     return Self.BuiltinIsBaseOf(Rhs->getTypeLoc().getBeginLoc(), LhsT, RhsT);
1649 
1650   case BTT_IsVirtualBaseOf: {
1651     const RecordType *BaseRecord = LhsT->getAs<RecordType>();
1652     const RecordType *DerivedRecord = RhsT->getAs<RecordType>();
1653 
1654     if (!BaseRecord || !DerivedRecord) {
1655       DiagnoseVLAInCXXTypeTrait(Self, Lhs,
1656                                 tok::kw___builtin_is_virtual_base_of);
1657       DiagnoseVLAInCXXTypeTrait(Self, Rhs,
1658                                 tok::kw___builtin_is_virtual_base_of);
1659       return false;
1660     }
1661 
1662     if (BaseRecord->isUnionType() || DerivedRecord->isUnionType())
1663       return false;
1664 
1665     if (!BaseRecord->isStructureOrClassType() ||
1666         !DerivedRecord->isStructureOrClassType())
1667       return false;
1668 
1669     if (Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1670                                  diag::err_incomplete_type))
1671       return false;
1672 
1673     return cast<CXXRecordDecl>(DerivedRecord->getDecl())
1674         ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
1675   }
1676   case BTT_IsSame:
1677     return Self.Context.hasSameType(LhsT, RhsT);
1678   case BTT_TypeCompatible: {
1679     // GCC ignores cv-qualifiers on arrays for this builtin.
1680     Qualifiers LhsQuals, RhsQuals;
1681     QualType Lhs = Self.getASTContext().getUnqualifiedArrayType(LhsT, LhsQuals);
1682     QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(RhsT, RhsQuals);
1683     return Self.Context.typesAreCompatible(Lhs, Rhs);
1684   }
1685   case BTT_IsConvertible:
1686   case BTT_IsConvertibleTo:
1687   case BTT_IsNothrowConvertible: {
1688     if (RhsT->isVoidType())
1689       return LhsT->isVoidType();
1690     llvm::BumpPtrAllocator OpaqueExprAllocator;
1691     ExprResult Result = CheckConvertibilityForTypeTraits(Self, Lhs, Rhs, KeyLoc,
1692                                                          OpaqueExprAllocator);
1693     if (Result.isInvalid())
1694       return false;
1695 
1696     if (BTT != BTT_IsNothrowConvertible)
1697       return true;
1698 
1699     return Self.canThrow(Result.get()) == CT_Cannot;
1700   }
1701 
1702   case BTT_IsAssignable:
1703   case BTT_IsNothrowAssignable:
1704   case BTT_IsTriviallyAssignable: {
1705     // C++11 [meta.unary.prop]p3:
1706     //   is_trivially_assignable is defined as:
1707     //     is_assignable<T, U>::value is true and the assignment, as defined by
1708     //     is_assignable, is known to call no operation that is not trivial
1709     //
1710     //   is_assignable is defined as:
1711     //     The expression declval<T>() = declval<U>() is well-formed when
1712     //     treated as an unevaluated operand (Clause 5).
1713     //
1714     //   For both, T and U shall be complete types, (possibly cv-qualified)
1715     //   void, or arrays of unknown bound.
1716     if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1717         Self.RequireCompleteType(
1718             Lhs->getTypeLoc().getBeginLoc(), LhsT,
1719             diag::err_incomplete_type_used_in_type_trait_expr))
1720       return false;
1721     if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1722         Self.RequireCompleteType(
1723             Rhs->getTypeLoc().getBeginLoc(), RhsT,
1724             diag::err_incomplete_type_used_in_type_trait_expr))
1725       return false;
1726 
1727     // cv void is never assignable.
1728     if (LhsT->isVoidType() || RhsT->isVoidType())
1729       return false;
1730 
1731     // Build expressions that emulate the effect of declval<T>() and
1732     // declval<U>().
1733     auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
1734       if (Ty->isObjectType() || Ty->isFunctionType())
1735         Ty = Self.Context.getRValueReferenceType(Ty);
1736       return {KeyLoc, Ty.getNonLValueExprType(Self.Context),
1737               Expr::getValueKindForType(Ty)};
1738     };
1739 
1740     auto Lhs = createDeclValExpr(LhsT);
1741     auto Rhs = createDeclValExpr(RhsT);
1742 
1743     // Attempt the assignment in an unevaluated context within a SFINAE
1744     // trap at translation unit scope.
1745     EnterExpressionEvaluationContext Unevaluated(
1746         Self, Sema::ExpressionEvaluationContext::Unevaluated);
1747     Sema::SFINAETrap SFINAE(Self, /*ForValidityCheck=*/true);
1748     Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
1749     ExprResult Result =
1750         Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs, &Rhs);
1751     if (Result.isInvalid())
1752       return false;
1753 
1754     // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1755     Self.CheckUnusedVolatileAssignment(Result.get());
1756 
1757     if (SFINAE.hasErrorOccurred())
1758       return false;
1759 
1760     if (BTT == BTT_IsAssignable)
1761       return true;
1762 
1763     if (BTT == BTT_IsNothrowAssignable)
1764       return Self.canThrow(Result.get()) == CT_Cannot;
1765 
1766     if (BTT == BTT_IsTriviallyAssignable) {
1767       // Under Objective-C ARC and Weak, if the destination has non-trivial
1768       // Objective-C lifetime, this is a non-trivial assignment.
1769       if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
1770         return false;
1771       ASTContext &Context = Self.getASTContext();
1772       if (Context.containsAddressDiscriminatedPointerAuth(LhsT) ||
1773           Context.containsAddressDiscriminatedPointerAuth(RhsT))
1774         return false;
1775       return !Result.get()->hasNonTrivialCall(Self.Context);
1776     }
1777 
1778     llvm_unreachable("unhandled type trait");
1779     return false;
1780   }
1781   case BTT_IsLayoutCompatible: {
1782     if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType())
1783       Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1784                                diag::err_incomplete_type);
1785     if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1786       Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1787                                diag::err_incomplete_type);
1788 
1789     DiagnoseVLAInCXXTypeTrait(Self, Lhs, tok::kw___is_layout_compatible);
1790     DiagnoseVLAInCXXTypeTrait(Self, Rhs, tok::kw___is_layout_compatible);
1791 
1792     return Self.IsLayoutCompatible(LhsT, RhsT);
1793   }
1794   case BTT_IsPointerInterconvertibleBaseOf: {
1795     if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1796         !Self.getASTContext().hasSameUnqualifiedType(LhsT, RhsT)) {
1797       Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1798                                diag::err_incomplete_type);
1799     }
1800 
1801     DiagnoseVLAInCXXTypeTrait(Self, Lhs,
1802                               tok::kw___is_pointer_interconvertible_base_of);
1803     DiagnoseVLAInCXXTypeTrait(Self, Rhs,
1804                               tok::kw___is_pointer_interconvertible_base_of);
1805 
1806     return Self.IsPointerInterconvertibleBaseOf(Lhs, Rhs);
1807   }
1808   case BTT_IsDeducible: {
1809     const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(LhsT);
1810     sema::TemplateDeductionInfo Info(KeyLoc);
1811     return Self.DeduceTemplateArgumentsFromType(
1812                TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), RhsT,
1813                Info) == TemplateDeductionResult::Success;
1814   }
1815   case BTT_IsScalarizedLayoutCompatible: {
1816     if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1817         Self.RequireCompleteType(Lhs->getTypeLoc().getBeginLoc(), LhsT,
1818                                  diag::err_incomplete_type))
1819       return true;
1820     if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1821         Self.RequireCompleteType(Rhs->getTypeLoc().getBeginLoc(), RhsT,
1822                                  diag::err_incomplete_type))
1823       return true;
1824 
1825     DiagnoseVLAInCXXTypeTrait(
1826         Self, Lhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1827     DiagnoseVLAInCXXTypeTrait(
1828         Self, Rhs, tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1829 
1830     return Self.HLSL().IsScalarizedLayoutCompatible(LhsT, RhsT);
1831   }
1832   default:
1833     llvm_unreachable("not a BTT");
1834   }
1835   llvm_unreachable("Unknown type trait or not implemented");
1836 }
1837 
ActOnArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,ParsedType Ty,Expr * DimExpr,SourceLocation RParen)1838 ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc,
1839                                      ParsedType Ty, Expr *DimExpr,
1840                                      SourceLocation RParen) {
1841   TypeSourceInfo *TSInfo;
1842   QualType T = GetTypeFromParser(Ty, &TSInfo);
1843   if (!TSInfo)
1844     TSInfo = Context.getTrivialTypeSourceInfo(T);
1845 
1846   return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1847 }
1848 
EvaluateArrayTypeTrait(Sema & Self,ArrayTypeTrait ATT,QualType T,Expr * DimExpr,SourceLocation KeyLoc)1849 static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,
1850                                        QualType T, Expr *DimExpr,
1851                                        SourceLocation KeyLoc) {
1852   assert(!T->isDependentType() && "Cannot evaluate traits of dependent type");
1853 
1854   switch (ATT) {
1855   case ATT_ArrayRank:
1856     if (T->isArrayType()) {
1857       unsigned Dim = 0;
1858       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1859         ++Dim;
1860         T = AT->getElementType();
1861       }
1862       return Dim;
1863     }
1864     return 0;
1865 
1866   case ATT_ArrayExtent: {
1867     llvm::APSInt Value;
1868     uint64_t Dim;
1869     if (Self.VerifyIntegerConstantExpression(
1870                 DimExpr, &Value, diag::err_dimension_expr_not_constant_integer)
1871             .isInvalid())
1872       return 0;
1873     if (Value.isSigned() && Value.isNegative()) {
1874       Self.Diag(KeyLoc, diag::err_dimension_expr_not_constant_integer)
1875           << DimExpr->getSourceRange();
1876       return 0;
1877     }
1878     Dim = Value.getLimitedValue();
1879 
1880     if (T->isArrayType()) {
1881       unsigned D = 0;
1882       bool Matched = false;
1883       while (const ArrayType *AT = Self.Context.getAsArrayType(T)) {
1884         if (Dim == D) {
1885           Matched = true;
1886           break;
1887         }
1888         ++D;
1889         T = AT->getElementType();
1890       }
1891 
1892       if (Matched && T->isArrayType()) {
1893         if (const ConstantArrayType *CAT =
1894                 Self.Context.getAsConstantArrayType(T))
1895           return CAT->getLimitedSize();
1896       }
1897     }
1898     return 0;
1899   }
1900   }
1901   llvm_unreachable("Unknown type trait or not implemented");
1902 }
1903 
BuildArrayTypeTrait(ArrayTypeTrait ATT,SourceLocation KWLoc,TypeSourceInfo * TSInfo,Expr * DimExpr,SourceLocation RParen)1904 ExprResult Sema::BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc,
1905                                      TypeSourceInfo *TSInfo, Expr *DimExpr,
1906                                      SourceLocation RParen) {
1907   QualType T = TSInfo->getType();
1908 
1909   // FIXME: This should likely be tracked as an APInt to remove any host
1910   // assumptions about the width of size_t on the target.
1911   uint64_t Value = 0;
1912   if (!T->isDependentType())
1913     Value = EvaluateArrayTypeTrait(*this, ATT, T, DimExpr, KWLoc);
1914 
1915   // While the specification for these traits from the Embarcadero C++
1916   // compiler's documentation says the return type is 'unsigned int', Clang
1917   // returns 'size_t'. On Windows, the primary platform for the Embarcadero
1918   // compiler, there is no difference. On several other platforms this is an
1919   // important distinction.
1920   return new (Context) ArrayTypeTraitExpr(KWLoc, ATT, TSInfo, Value, DimExpr,
1921                                           RParen, Context.getSizeType());
1922 }
1923 
ActOnExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)1924 ExprResult Sema::ActOnExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc,
1925                                       Expr *Queried, SourceLocation RParen) {
1926   // If error parsing the expression, ignore.
1927   if (!Queried)
1928     return ExprError();
1929 
1930   ExprResult Result = BuildExpressionTrait(ET, KWLoc, Queried, RParen);
1931 
1932   return Result;
1933 }
1934 
EvaluateExpressionTrait(ExpressionTrait ET,Expr * E)1935 static bool EvaluateExpressionTrait(ExpressionTrait ET, Expr *E) {
1936   switch (ET) {
1937   case ET_IsLValueExpr:
1938     return E->isLValue();
1939   case ET_IsRValueExpr:
1940     return E->isPRValue();
1941   }
1942   llvm_unreachable("Expression trait not covered by switch");
1943 }
1944 
BuildExpressionTrait(ExpressionTrait ET,SourceLocation KWLoc,Expr * Queried,SourceLocation RParen)1945 ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc,
1946                                       Expr *Queried, SourceLocation RParen) {
1947   if (Queried->isTypeDependent()) {
1948     // Delay type-checking for type-dependent expressions.
1949   } else if (Queried->hasPlaceholderType()) {
1950     ExprResult PE = CheckPlaceholderExpr(Queried);
1951     if (PE.isInvalid())
1952       return ExprError();
1953     return BuildExpressionTrait(ET, KWLoc, PE.get(), RParen);
1954   }
1955 
1956   bool Value = EvaluateExpressionTrait(ET, Queried);
1957 
1958   return new (Context)
1959       ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
1960 }
1961 
StdNameToTypeTrait(StringRef Name)1962 static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
1963   return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1964       .Case("is_trivially_relocatable",
1965             TypeTrait::UTT_IsCppTriviallyRelocatable)
1966       .Case("is_replaceable", TypeTrait::UTT_IsReplaceable)
1967       .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable)
1968       .Case("is_assignable", TypeTrait::BTT_IsAssignable)
1969       .Case("is_empty", TypeTrait::UTT_IsEmpty)
1970       .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout)
1971       .Case("is_constructible", TypeTrait::TT_IsConstructible)
1972       .Default(std::nullopt);
1973 }
1974 
1975 using ExtractedTypeTraitInfo =
1976     std::optional<std::pair<TypeTrait, llvm::SmallVector<QualType, 1>>>;
1977 
1978 // Recognize type traits that are builting type traits, or known standard
1979 // type traits in <type_traits>. Note that at this point we assume the
1980 // trait evaluated to false, so we need only to recognize the shape of the
1981 // outer-most symbol.
ExtractTypeTraitFromExpression(const Expr * E)1982 static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E) {
1983   llvm::SmallVector<QualType, 1> Args;
1984   std::optional<TypeTrait> Trait;
1985 
1986   // builtins
1987   if (const auto *TraitExpr = dyn_cast<TypeTraitExpr>(E)) {
1988     Trait = TraitExpr->getTrait();
1989     for (const auto *Arg : TraitExpr->getArgs())
1990       Args.push_back(Arg->getType());
1991     return {{Trait.value(), std::move(Args)}};
1992   }
1993   const auto *Ref = dyn_cast<DeclRefExpr>(E);
1994   if (!Ref)
1995     return std::nullopt;
1996 
1997   // std::is_xxx_v<>
1998   if (const auto *VD =
1999           dyn_cast<VarTemplateSpecializationDecl>(Ref->getDecl())) {
2000     if (!VD->isInStdNamespace())
2001       return std::nullopt;
2002     StringRef Name = VD->getIdentifier()->getName();
2003     if (!Name.consume_back("_v"))
2004       return std::nullopt;
2005     Trait = StdNameToTypeTrait(Name);
2006     if (!Trait)
2007       return std::nullopt;
2008     for (const auto &Arg : VD->getTemplateArgs().asArray()) {
2009       if (Arg.getKind() == TemplateArgument::ArgKind::Pack) {
2010         for (const auto &InnerArg : Arg.pack_elements())
2011           Args.push_back(InnerArg.getAsType());
2012       } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2013         Args.push_back(Arg.getAsType());
2014       } else {
2015         llvm_unreachable("Unexpected kind");
2016       }
2017     }
2018     return {{Trait.value(), std::move(Args)}};
2019   }
2020 
2021   // std::is_xxx<>::value
2022   if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
2023       Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
2024     const Type *T = Ref->getQualifier()->getAsType();
2025     if (!T)
2026       return std::nullopt;
2027     const TemplateSpecializationType *Ts =
2028         T->getAs<TemplateSpecializationType>();
2029     if (!Ts)
2030       return std::nullopt;
2031     const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
2032     if (!D || !D->isInStdNamespace())
2033       return std::nullopt;
2034     Trait = StdNameToTypeTrait(D->getIdentifier()->getName());
2035     if (!Trait)
2036       return std::nullopt;
2037     for (const auto &Arg : Ts->template_arguments())
2038       Args.push_back(Arg.getAsType());
2039     return {{Trait.value(), std::move(Args)}};
2040   }
2041   return std::nullopt;
2042 }
2043 
DiagnoseNonDefaultMovable(Sema & SemaRef,SourceLocation Loc,const CXXRecordDecl * D)2044 static void DiagnoseNonDefaultMovable(Sema &SemaRef, SourceLocation Loc,
2045                                       const CXXRecordDecl *D) {
2046   if (D->isUnion()) {
2047     auto DiagSPM = [&](CXXSpecialMemberKind K, bool Has) {
2048       if (Has)
2049         SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2050             << diag::TraitNotSatisfiedReason::UnionWithUserDeclaredSMF << K;
2051     };
2052     DiagSPM(CXXSpecialMemberKind::CopyConstructor,
2053             D->hasUserDeclaredCopyConstructor());
2054     DiagSPM(CXXSpecialMemberKind::CopyAssignment,
2055             D->hasUserDeclaredCopyAssignment());
2056     DiagSPM(CXXSpecialMemberKind::MoveConstructor,
2057             D->hasUserDeclaredMoveConstructor());
2058     DiagSPM(CXXSpecialMemberKind::MoveAssignment,
2059             D->hasUserDeclaredMoveAssignment());
2060     return;
2061   }
2062 
2063   if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {
2064     const auto *Decl = cast_or_null<CXXConstructorDecl>(
2065         LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2066     if (Decl && Decl->isUserProvided())
2067       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2068           << diag::TraitNotSatisfiedReason::UserProvidedCtr
2069           << Decl->isMoveConstructor() << Decl->getSourceRange();
2070   }
2071   if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {
2072     CXXMethodDecl *Decl =
2073         LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2074     if (Decl && Decl->isUserProvided())
2075       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2076           << diag::TraitNotSatisfiedReason::UserProvidedAssign
2077           << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2078   }
2079   if (CXXDestructorDecl *Dtr = D->getDestructor()) {
2080     Dtr = Dtr->getCanonicalDecl();
2081     if (Dtr->isUserProvided() && !Dtr->isDefaulted())
2082       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2083           << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2084           << Dtr->getSourceRange();
2085   }
2086 }
2087 
DiagnoseNonTriviallyRelocatableReason(Sema & SemaRef,SourceLocation Loc,const CXXRecordDecl * D)2088 static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef,
2089                                                   SourceLocation Loc,
2090                                                   const CXXRecordDecl *D) {
2091   for (const CXXBaseSpecifier &B : D->bases()) {
2092     assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2093     if (B.isVirtual())
2094       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2095           << diag::TraitNotSatisfiedReason::VBase << B.getType()
2096           << B.getSourceRange();
2097     if (!SemaRef.IsCXXTriviallyRelocatableType(B.getType()))
2098       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2099           << diag::TraitNotSatisfiedReason::NTRBase << B.getType()
2100           << B.getSourceRange();
2101   }
2102   for (const FieldDecl *Field : D->fields()) {
2103     if (!Field->getType()->isReferenceType() &&
2104         !SemaRef.IsCXXTriviallyRelocatableType(Field->getType()))
2105       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2106           << diag::TraitNotSatisfiedReason::NTRField << Field
2107           << Field->getType() << Field->getSourceRange();
2108   }
2109   if (D->hasDeletedDestructor())
2110     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2111         << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2112         << D->getDestructor()->getSourceRange();
2113 
2114   if (D->hasAttr<TriviallyRelocatableAttr>())
2115     return;
2116   DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2117 }
2118 
DiagnoseNonTriviallyRelocatableReason(Sema & SemaRef,SourceLocation Loc,QualType T)2119 static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef,
2120                                                   SourceLocation Loc,
2121                                                   QualType T) {
2122   SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2123       << T << diag::TraitName::TriviallyRelocatable;
2124   if (T->isVariablyModifiedType())
2125     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2126         << diag::TraitNotSatisfiedReason::VLA;
2127 
2128   if (T->isReferenceType())
2129     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2130         << diag::TraitNotSatisfiedReason::Ref;
2131   T = T.getNonReferenceType();
2132 
2133   if (T.hasNonTrivialObjCLifetime())
2134     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2135         << diag::TraitNotSatisfiedReason::HasArcLifetime;
2136 
2137   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2138   if (!D || D->isInvalidDecl())
2139     return;
2140 
2141   if (D->hasDefinition())
2142     DiagnoseNonTriviallyRelocatableReason(SemaRef, Loc, D);
2143 
2144   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2145 }
2146 
DiagnoseNonReplaceableReason(Sema & SemaRef,SourceLocation Loc,const CXXRecordDecl * D)2147 static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc,
2148                                          const CXXRecordDecl *D) {
2149   for (const CXXBaseSpecifier &B : D->bases()) {
2150     assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2151     if (!SemaRef.IsCXXReplaceableType(B.getType()))
2152       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2153           << diag::TraitNotSatisfiedReason::NonReplaceableBase << B.getType()
2154           << B.getSourceRange();
2155   }
2156   for (const FieldDecl *Field : D->fields()) {
2157     if (!SemaRef.IsCXXReplaceableType(Field->getType()))
2158       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2159           << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2160           << Field->getType() << Field->getSourceRange();
2161   }
2162   if (D->hasDeletedDestructor())
2163     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2164         << diag::TraitNotSatisfiedReason::DeletedDtr << /*Deleted*/ 0
2165         << D->getDestructor()->getSourceRange();
2166 
2167   if (!D->hasSimpleMoveConstructor() && !D->hasSimpleCopyConstructor()) {
2168     const auto *Decl = cast<CXXConstructorDecl>(
2169         LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/false));
2170     if (Decl && Decl->isDeleted())
2171       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2172           << diag::TraitNotSatisfiedReason::DeletedCtr
2173           << Decl->isMoveConstructor() << Decl->getSourceRange();
2174   }
2175   if (!D->hasSimpleMoveAssignment() && !D->hasSimpleCopyAssignment()) {
2176     CXXMethodDecl *Decl =
2177         LookupSpecialMemberFromXValue(SemaRef, D, /*Assign=*/true);
2178     if (Decl && Decl->isDeleted())
2179       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2180           << diag::TraitNotSatisfiedReason::DeletedAssign
2181           << Decl->isMoveAssignmentOperator() << Decl->getSourceRange();
2182   }
2183 
2184   if (D->hasAttr<ReplaceableAttr>())
2185     return;
2186   DiagnoseNonDefaultMovable(SemaRef, Loc, D);
2187 }
2188 
DiagnoseNonReplaceableReason(Sema & SemaRef,SourceLocation Loc,QualType T)2189 static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc,
2190                                          QualType T) {
2191   SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2192       << T << diag::TraitName::Replaceable;
2193 
2194   if (T->isVariablyModifiedType())
2195     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2196         << diag::TraitNotSatisfiedReason::VLA;
2197 
2198   if (T->isReferenceType())
2199     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2200         << diag::TraitNotSatisfiedReason::Ref;
2201   T = T.getNonReferenceType();
2202 
2203   if (T.isConstQualified())
2204     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2205         << diag::TraitNotSatisfiedReason::Const;
2206 
2207   if (T.isVolatileQualified())
2208     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2209         << diag::TraitNotSatisfiedReason::Volatile;
2210 
2211   bool IsArray = T->isArrayType();
2212   T = SemaRef.getASTContext().getBaseElementType(T.getUnqualifiedType());
2213 
2214   if (T->isScalarType())
2215     return;
2216 
2217   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2218   if (!D) {
2219     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2220         << diag::TraitNotSatisfiedReason::NotScalarOrClass << IsArray;
2221     return;
2222   }
2223 
2224   if (D->isInvalidDecl())
2225     return;
2226 
2227   if (D->hasDefinition())
2228     DiagnoseNonReplaceableReason(SemaRef, Loc, D);
2229 
2230   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2231 }
2232 
DiagnoseNonTriviallyCopyableReason(Sema & SemaRef,SourceLocation Loc,const CXXRecordDecl * D)2233 static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
2234                                                SourceLocation Loc,
2235                                                const CXXRecordDecl *D) {
2236   for (const CXXBaseSpecifier &B : D->bases()) {
2237     assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2238     if (B.isVirtual())
2239       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2240           << diag::TraitNotSatisfiedReason::VBase << B.getType()
2241           << B.getSourceRange();
2242     if (!B.getType().isTriviallyCopyableType(D->getASTContext())) {
2243       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2244           << diag::TraitNotSatisfiedReason::NTCBase << B.getType()
2245           << B.getSourceRange();
2246     }
2247   }
2248   for (const FieldDecl *Field : D->fields()) {
2249     if (!Field->getType().isTriviallyCopyableType(Field->getASTContext()))
2250       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2251           << diag::TraitNotSatisfiedReason::NTCField << Field
2252           << Field->getType() << Field->getSourceRange();
2253   }
2254   CXXDestructorDecl *Dtr = D->getDestructor();
2255   if (D->hasDeletedDestructor() || (Dtr && !Dtr->isTrivial()))
2256     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2257         << diag::TraitNotSatisfiedReason::DeletedDtr
2258         << !D->hasDeletedDestructor() << D->getDestructor()->getSourceRange();
2259 
2260   for (const CXXMethodDecl *Method : D->methods()) {
2261     if (Method->isTrivial() || !Method->isUserProvided()) {
2262       continue;
2263     }
2264     auto SpecialMemberKind =
2265         SemaRef.getDefaultedFunctionKind(Method).asSpecialMember();
2266     switch (SpecialMemberKind) {
2267     case CXXSpecialMemberKind::CopyConstructor:
2268     case CXXSpecialMemberKind::MoveConstructor:
2269     case CXXSpecialMemberKind::CopyAssignment:
2270     case CXXSpecialMemberKind::MoveAssignment: {
2271       bool IsAssignment =
2272           SpecialMemberKind == CXXSpecialMemberKind::CopyAssignment ||
2273           SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2274       bool IsMove =
2275           SpecialMemberKind == CXXSpecialMemberKind::MoveConstructor ||
2276           SpecialMemberKind == CXXSpecialMemberKind::MoveAssignment;
2277 
2278       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2279           << (IsAssignment ? diag::TraitNotSatisfiedReason::UserProvidedAssign
2280                            : diag::TraitNotSatisfiedReason::UserProvidedCtr)
2281           << IsMove << Method->getSourceRange();
2282       break;
2283     }
2284     default:
2285       break;
2286     }
2287   }
2288 }
2289 
DiagnoseNonConstructibleReason(Sema & SemaRef,SourceLocation Loc,const llvm::SmallVector<clang::QualType,1> & Ts)2290 static void DiagnoseNonConstructibleReason(
2291     Sema &SemaRef, SourceLocation Loc,
2292     const llvm::SmallVector<clang::QualType, 1> &Ts) {
2293   if (Ts.empty()) {
2294     return;
2295   }
2296 
2297   bool ContainsVoid = false;
2298   for (const QualType &ArgTy : Ts) {
2299     ContainsVoid |= ArgTy->isVoidType();
2300   }
2301 
2302   if (ContainsVoid)
2303     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2304         << diag::TraitNotSatisfiedReason::CVVoidType;
2305 
2306   QualType T = Ts[0];
2307   if (T->isFunctionType())
2308     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2309         << diag::TraitNotSatisfiedReason::FunctionType;
2310 
2311   if (T->isIncompleteArrayType())
2312     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2313         << diag::TraitNotSatisfiedReason::IncompleteArrayType;
2314 
2315   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2316   if (!D || D->isInvalidDecl() || !D->hasDefinition())
2317     return;
2318 
2319   llvm::BumpPtrAllocator OpaqueExprAllocator;
2320   SmallVector<Expr *, 2> ArgExprs;
2321   ArgExprs.reserve(Ts.size() - 1);
2322   for (unsigned I = 1, N = Ts.size(); I != N; ++I) {
2323     QualType ArgTy = Ts[I];
2324     if (ArgTy->isObjectType() || ArgTy->isFunctionType())
2325       ArgTy = SemaRef.Context.getRValueReferenceType(ArgTy);
2326     ArgExprs.push_back(
2327         new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2328             OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(SemaRef.Context),
2329                             Expr::getValueKindForType(ArgTy)));
2330   }
2331 
2332   EnterExpressionEvaluationContext Unevaluated(
2333       SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
2334   Sema::ContextRAII TUContext(SemaRef,
2335                               SemaRef.Context.getTranslationUnitDecl());
2336   InitializedEntity To(InitializedEntity::InitializeTemporary(T));
2337   InitializationKind InitKind(InitializationKind::CreateDirect(Loc, Loc, Loc));
2338   InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2339 
2340   Init.Diagnose(SemaRef, To, InitKind, ArgExprs);
2341   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2342 }
2343 
DiagnoseNonTriviallyCopyableReason(Sema & SemaRef,SourceLocation Loc,QualType T)2344 static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
2345                                                SourceLocation Loc, QualType T) {
2346   SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2347       << T << diag::TraitName::TriviallyCopyable;
2348 
2349   if (T->isReferenceType())
2350     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2351         << diag::TraitNotSatisfiedReason::Ref;
2352 
2353   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2354   if (!D || D->isInvalidDecl())
2355     return;
2356 
2357   if (D->hasDefinition())
2358     DiagnoseNonTriviallyCopyableReason(SemaRef, Loc, D);
2359 
2360   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2361 }
2362 
DiagnoseNonAssignableReason(Sema & SemaRef,SourceLocation Loc,QualType T,QualType U)2363 static void DiagnoseNonAssignableReason(Sema &SemaRef, SourceLocation Loc,
2364                                         QualType T, QualType U) {
2365   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2366 
2367   auto createDeclValExpr = [&](QualType Ty) -> OpaqueValueExpr {
2368     if (Ty->isObjectType() || Ty->isFunctionType())
2369       Ty = SemaRef.Context.getRValueReferenceType(Ty);
2370     return {Loc, Ty.getNonLValueExprType(SemaRef.Context),
2371             Expr::getValueKindForType(Ty)};
2372   };
2373 
2374   auto LHS = createDeclValExpr(T);
2375   auto RHS = createDeclValExpr(U);
2376 
2377   EnterExpressionEvaluationContext Unevaluated(
2378       SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
2379   Sema::ContextRAII TUContext(SemaRef,
2380                               SemaRef.Context.getTranslationUnitDecl());
2381   SemaRef.BuildBinOp(/*S=*/nullptr, Loc, BO_Assign, &LHS, &RHS);
2382 
2383   if (!D || D->isInvalidDecl())
2384     return;
2385 
2386   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2387 }
2388 
DiagnoseIsEmptyReason(Sema & S,SourceLocation Loc,const CXXRecordDecl * D)2389 static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc,
2390                                   const CXXRecordDecl *D) {
2391   // Non-static data members (ignore zero-width bit‐fields).
2392   for (const auto *Field : D->fields()) {
2393     if (Field->isZeroLengthBitField())
2394       continue;
2395     if (Field->isBitField()) {
2396       S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2397           << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2398           << Field->getSourceRange();
2399       continue;
2400     }
2401     S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2402         << diag::TraitNotSatisfiedReason::NonEmptyMember << Field
2403         << Field->getType() << Field->getSourceRange();
2404   }
2405 
2406   // Virtual functions.
2407   for (const auto *M : D->methods()) {
2408     if (M->isVirtual()) {
2409       S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2410           << diag::TraitNotSatisfiedReason::VirtualFunction << M
2411           << M->getSourceRange();
2412       break;
2413     }
2414   }
2415 
2416   // Virtual bases and non-empty bases.
2417   for (const auto &B : D->bases()) {
2418     const auto *BR = B.getType()->getAsCXXRecordDecl();
2419     if (!BR || BR->isInvalidDecl())
2420       continue;
2421     if (B.isVirtual()) {
2422       S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2423           << diag::TraitNotSatisfiedReason::VBase << B.getType()
2424           << B.getSourceRange();
2425     }
2426     if (!BR->isEmpty()) {
2427       S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2428           << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2429           << B.getSourceRange();
2430     }
2431   }
2432 }
2433 
DiagnoseIsEmptyReason(Sema & S,SourceLocation Loc,QualType T)2434 static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, QualType T) {
2435   // Emit primary "not empty" diagnostic.
2436   S.Diag(Loc, diag::note_unsatisfied_trait) << T << diag::TraitName::Empty;
2437 
2438   // While diagnosing is_empty<T>, we want to look at the actual type, not a
2439   // reference or an array of it. So we need to massage the QualType param to
2440   // strip refs and arrays.
2441   if (T->isReferenceType())
2442     S.Diag(Loc, diag::note_unsatisfied_trait_reason)
2443         << diag::TraitNotSatisfiedReason::Ref;
2444   T = T.getNonReferenceType();
2445 
2446   if (auto *AT = S.Context.getAsArrayType(T))
2447     T = AT->getElementType();
2448 
2449   if (auto *D = T->getAsCXXRecordDecl()) {
2450     if (D->hasDefinition()) {
2451       DiagnoseIsEmptyReason(S, Loc, D);
2452       S.Diag(D->getLocation(), diag::note_defined_here) << D;
2453     }
2454   }
2455 }
2456 
hasMultipleDataBaseClassesWithFields(const CXXRecordDecl * D)2457 static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D) {
2458   int NumBasesWithFields = 0;
2459   for (const CXXBaseSpecifier &Base : D->bases()) {
2460     const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
2461     if (!BaseRD || BaseRD->isInvalidDecl())
2462       continue;
2463 
2464     for (const FieldDecl *Field : BaseRD->fields()) {
2465       if (!Field->isUnnamedBitField()) {
2466         if (++NumBasesWithFields > 1)
2467           return true; // found more than one base class with fields
2468         break;         // no need to check further fields in this base class
2469       }
2470     }
2471   }
2472   return false;
2473 }
2474 
DiagnoseNonStandardLayoutReason(Sema & SemaRef,SourceLocation Loc,const CXXRecordDecl * D)2475 static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
2476                                             const CXXRecordDecl *D) {
2477   for (const CXXBaseSpecifier &B : D->bases()) {
2478     assert(B.getType()->getAsCXXRecordDecl() && "invalid base?");
2479     if (B.isVirtual()) {
2480       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2481           << diag::TraitNotSatisfiedReason::VBase << B.getType()
2482           << B.getSourceRange();
2483     }
2484     if (!B.getType()->isStandardLayoutType()) {
2485       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2486           << diag::TraitNotSatisfiedReason::NonStandardLayoutBase << B.getType()
2487           << B.getSourceRange();
2488     }
2489   }
2490   // Check for mixed access specifiers in fields.
2491   const FieldDecl *FirstField = nullptr;
2492   AccessSpecifier FirstAccess = AS_none;
2493 
2494   for (const FieldDecl *Field : D->fields()) {
2495     if (Field->isUnnamedBitField())
2496       continue;
2497 
2498     // Record the first field we see
2499     if (!FirstField) {
2500       FirstField = Field;
2501       FirstAccess = Field->getAccess();
2502       continue;
2503     }
2504 
2505     // Check if the field has a different access specifier than the first one.
2506     if (Field->getAccess() != FirstAccess) {
2507       // Emit a diagnostic about mixed access specifiers.
2508       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2509           << diag::TraitNotSatisfiedReason::MixedAccess;
2510 
2511       SemaRef.Diag(FirstField->getLocation(), diag::note_defined_here)
2512           << FirstField;
2513 
2514       SemaRef.Diag(Field->getLocation(), diag::note_unsatisfied_trait_reason)
2515           << diag::TraitNotSatisfiedReason::MixedAccessField << Field
2516           << FirstField;
2517 
2518       // No need to check further fields, as we already found mixed access.
2519       break;
2520     }
2521   }
2522   if (hasMultipleDataBaseClassesWithFields(D)) {
2523     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2524         << diag::TraitNotSatisfiedReason::MultipleDataBase;
2525   }
2526   if (D->isPolymorphic()) {
2527     // Find the best location to point “defined here” at.
2528     const CXXMethodDecl *VirtualMD = nullptr;
2529     // First, look for a virtual method.
2530     for (const auto *M : D->methods()) {
2531       if (M->isVirtual()) {
2532         VirtualMD = M;
2533         break;
2534       }
2535     }
2536     if (VirtualMD) {
2537       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2538           << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2539       SemaRef.Diag(VirtualMD->getLocation(), diag::note_defined_here)
2540           << VirtualMD;
2541     } else {
2542       // If no virtual method, point to the record declaration itself.
2543       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2544           << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2545       SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2546     }
2547   }
2548   for (const FieldDecl *Field : D->fields()) {
2549     if (!Field->getType()->isStandardLayoutType()) {
2550       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2551           << diag::TraitNotSatisfiedReason::NonStandardLayoutMember << Field
2552           << Field->getType() << Field->getSourceRange();
2553     }
2554   }
2555   // Find any indirect base classes that have fields.
2556   if (D->hasDirectFields()) {
2557     const CXXRecordDecl *Indirect = nullptr;
2558     D->forallBases([&](const CXXRecordDecl *BaseDef) {
2559       if (BaseDef->hasDirectFields()) {
2560         Indirect = BaseDef;
2561         return false; // stop traversal
2562       }
2563       return true; // continue to the next base
2564     });
2565     if (Indirect) {
2566       SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2567           << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2568           << Indirect->getSourceRange();
2569     }
2570   }
2571 }
2572 
DiagnoseNonStandardLayoutReason(Sema & SemaRef,SourceLocation Loc,QualType T)2573 static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
2574                                             QualType T) {
2575   SemaRef.Diag(Loc, diag::note_unsatisfied_trait)
2576       << T << diag::TraitName::StandardLayout;
2577 
2578   // Check type-level exclusion first.
2579   if (T->isVariablyModifiedType()) {
2580     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2581         << diag::TraitNotSatisfiedReason::VLA;
2582     return;
2583   }
2584 
2585   if (T->isReferenceType()) {
2586     SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason)
2587         << diag::TraitNotSatisfiedReason::Ref;
2588     return;
2589   }
2590   T = T.getNonReferenceType();
2591   const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2592   if (!D || D->isInvalidDecl())
2593     return;
2594 
2595   if (D->hasDefinition())
2596     DiagnoseNonStandardLayoutReason(SemaRef, Loc, D);
2597 
2598   SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D;
2599 }
2600 
DiagnoseTypeTraitDetails(const Expr * E)2601 void Sema::DiagnoseTypeTraitDetails(const Expr *E) {
2602   E = E->IgnoreParenImpCasts();
2603   if (E->containsErrors())
2604     return;
2605 
2606   ExtractedTypeTraitInfo TraitInfo = ExtractTypeTraitFromExpression(E);
2607   if (!TraitInfo)
2608     return;
2609 
2610   const auto &[Trait, Args] = TraitInfo.value();
2611   switch (Trait) {
2612   case UTT_IsCppTriviallyRelocatable:
2613     DiagnoseNonTriviallyRelocatableReason(*this, E->getBeginLoc(), Args[0]);
2614     break;
2615   case UTT_IsReplaceable:
2616     DiagnoseNonReplaceableReason(*this, E->getBeginLoc(), Args[0]);
2617     break;
2618   case UTT_IsTriviallyCopyable:
2619     DiagnoseNonTriviallyCopyableReason(*this, E->getBeginLoc(), Args[0]);
2620     break;
2621   case BTT_IsAssignable:
2622     DiagnoseNonAssignableReason(*this, E->getBeginLoc(), Args[0], Args[1]);
2623     break;
2624   case UTT_IsEmpty:
2625     DiagnoseIsEmptyReason(*this, E->getBeginLoc(), Args[0]);
2626     break;
2627   case UTT_IsStandardLayout:
2628     DiagnoseNonStandardLayoutReason(*this, E->getBeginLoc(), Args[0]);
2629     break;
2630   case TT_IsConstructible:
2631     DiagnoseNonConstructibleReason(*this, E->getBeginLoc(), Args);
2632     break;
2633   default:
2634     break;
2635   }
2636 }
2637