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
27using namespace clang;
28
29static 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 T: SemaRef.getASTContext().getTagDeclType(Decl: 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(Op: OO_Equal);
47 else
48 Name =
49 SemaRef.getASTContext().DeclarationNames.getCXXConstructorName(Ty: 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(Ctx&: 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(D: CandDecl, AS: clang::AS_none);
79 auto CtorInfo = getConstructorInfo(ND: Cand);
80 if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Val: Cand->getUnderlyingDecl())) {
81 if (Assign)
82 SemaRef.AddMethodCandidate(Method: M, FoundDecl: Cand, ActingContext: const_cast<CXXRecordDecl *>(RD),
83 ObjectType: ThisTy, ObjectClassification: Classification,
84 Args: llvm::ArrayRef(&Arg, NumArgs), CandidateSet&: OCS, SuppressUserConversions: true);
85 else {
86 assert(CtorInfo);
87 SemaRef.AddOverloadCandidate(Function: CtorInfo.Constructor, FoundDecl: CtorInfo.FoundDecl,
88 Args: llvm::ArrayRef(&Arg, NumArgs), CandidateSet&: OCS,
89 /*SuppressUserConversions*/ true);
90 }
91 } else if (FunctionTemplateDecl *Tmpl =
92 dyn_cast<FunctionTemplateDecl>(Val: Cand->getUnderlyingDecl())) {
93 if (Assign)
94 SemaRef.AddMethodTemplateCandidate(
95 MethodTmpl: Tmpl, FoundDecl: Cand, ActingContext: const_cast<CXXRecordDecl *>(RD), ExplicitTemplateArgs: nullptr, ObjectType: ThisTy,
96 ObjectClassification: Classification, Args: llvm::ArrayRef(&Arg, NumArgs), CandidateSet&: OCS, SuppressUserConversions: true);
97 else {
98 assert(CtorInfo);
99 SemaRef.AddTemplateOverloadCandidate(
100 FunctionTemplate: CtorInfo.ConstructorTmpl, FoundDecl: CtorInfo.FoundDecl, ExplicitTemplateArgs: nullptr,
101 Args: llvm::ArrayRef(&Arg, NumArgs), CandidateSet&: OCS, SuppressUserConversions: true);
102 }
103 }
104 }
105
106 OverloadCandidateSet::iterator Best;
107 switch (OCS.BestViableFunction(S&: SemaRef, Loc: LookupLoc, Best)) {
108 case OR_Success:
109 case OR_Deleted:
110 return cast<CXXMethodDecl>(Val: Best->Function)->getCanonicalDecl();
111 default:
112 return nullptr;
113 }
114}
115
116static 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, RD: D, /*Assign=*/false);
126 return Decl && (AllowUserDefined || !Decl->isUserProvided()) &&
127 !Decl->isDeleted();
128}
129
130static 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, RD: 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.
155static 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...
179static 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(T: 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(T: 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 T: 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
215static 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(T: 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(T: Field->getType()))
233 return false;
234 }
235 return !D->hasDeletedDestructor();
236}
237
238ASTContext::CXXRecordDeclRelocationInfo
239Sema::CheckCXX2CRelocatableAndReplaceable(const CXXRecordDecl *D) {
240 ASTContext::CXXRecordDeclRelocationInfo Info{.IsRelocatable: false, .IsReplaceable: 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(SemaRef&: *this, D,
251 /*AllowUserDefined=*/true) &&
252 hasSuitableMoveAssignmentOperatorForRelocation(
253 SemaRef&: *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(SemaRef&: *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(SemaRef&: *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(SemaRef&: *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
314bool 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(D: &RD);
320 getASTContext().setRelocationInfoForCXXRecord(&RD, Info);
321 return Info.IsRelocatable;
322}
323
324bool Sema::IsCXXTriviallyRelocatableType(QualType Type) {
325 QualType BaseElementType = getASTContext().getBaseElementType(QT: 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(T: 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: *RD);
344
345 return false;
346}
347
348static 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(D: RD);
354 S.getASTContext().setRelocationInfoForCXXRecord(RD, Info);
355 return Info.IsReplaceable;
356}
357
358bool 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(QT: 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(S&: *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.
380static bool DiagnoseVLAInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
381 clang::tok::TokenKind TypeTraitID) {
382 if (!T->getType()->isVariableArrayType())
383 return false;
384
385 S.Diag(Loc: T->getTypeLoc().getBeginLoc(), DiagID: 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.
394static bool DiagnoseAtomicInCXXTypeTrait(Sema &S, const TypeSourceInfo *T,
395 clang::tok::TokenKind TypeTraitID) {
396 if (!T->getType()->isAtomicType())
397 return false;
398
399 S.Diag(Loc: T->getTypeLoc().getBeginLoc(), DiagID: 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.
410static 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, T: ArgTy, DiagID: 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, T: ArgTy, DiagID: 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, T: ArgTy, DiagID: 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, T: ArgTy, DiagID: 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, T: ArgTy, DiagID: diag::err_incomplete_type_used_in_type_trait_expr);
557 }
558}
559
560static 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>(Val: 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(R&: Res, LookupCtx: 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>(Val: *Op))
578 continue;
579
580 CXXMethodDecl *Operator = cast<CXXMethodDecl>(Val: *Op);
581 if ((Operator->*IsDesiredOp)()) {
582 FoundOperator = true;
583 auto *CPT = Operator->getType()->castAs<FunctionProtoType>();
584 CPT = Self.ResolveExceptionSpec(Loc: KeyLoc, FPT: CPT);
585 if (!CPT || !CPT->isNothrow())
586 return false;
587 }
588 }
589 return FoundOperator;
590 }
591 return false;
592}
593
594static 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: S.TUScope, OpLoc: {}, Opc: BinaryOperatorKind::BO_EQ, Functions);
616
617 auto Result = S.CreateOverloadedBinOp(OpLoc: KeyLoc, Opc: BinaryOperatorKind::BO_EQ,
618 Fns: Functions, LHS: &Operand, RHS: &Operand);
619 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
620 return false;
621
622 const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Val: Result.get());
623 if (!CallExpr)
624 return false;
625 const auto *Callee = CallExpr->getDirectCallee();
626 auto ParamT = Callee->getParamDecl(i: 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(Range: Decl->bases(),
637 P: [&](const CXXBaseSpecifier &BS) {
638 if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
639 return HasNonDeletedDefaultedEqualityComparison(
640 S, Decl: RD, KeyLoc);
641 return true;
642 }) &&
643 llvm::all_of(Range: Decl->fields(), P: [&](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, Decl: RD, KeyLoc);
653 return true;
654 });
655}
656
657static 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, Decl: RD, KeyLoc))
666 return false;
667 }
668
669 return S.getASTContext().hasUniqueObjectRepresentations(
670 Ty: CanonicalType, /*CheckIfTriviallyCopyable=*/false);
671}
672
673static bool IsTriviallyRelocatableType(Sema &SemaRef, QualType T) {
674 QualType BaseElementType = SemaRef.getASTContext().getBaseElementType(QT: 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: *RD))
689 return true;
690
691 if (const auto *RD = BaseElementType->getAsRecordDecl())
692 return RD->canPassInRegisters();
693
694 if (BaseElementType.isTriviallyCopyableType(Context: 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
707static 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(Ctx: 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(S&: Self, T: TInfo, TypeTraitID: 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(S&: Self, T: TInfo, TypeTraitID: 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(Context: C);
806 case UTT_IsTriviallyCopyable:
807 return T.isTriviallyCopyableType(Context: C);
808 case UTT_IsStandardLayout:
809 return T->isStandardLayoutType();
810 case UTT_IsPOD:
811 return T.isPODType(Context: C);
812 case UTT_IsLiteral:
813 return T->isLiteralType(Ctx: 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(Context: C))
873 return true;
874 if (CXXRecordDecl *RD = C.getBaseElementType(QT: 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(Context: C))
883 return true;
884 if (CXXRecordDecl *RD = C.getBaseElementType(QT: 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(Context: 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(Context: C))
905 return true;
906 if (CXXRecordDecl *RD = C.getBaseElementType(QT: 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(Context: 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(QT: T)->getAsCXXRecordDecl()) {
960 CXXDestructorDecl *Destructor = Self.LookupDestructor(Class: 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(Loc: KeyLoc, FPT: 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(Context: 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(QT: 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(QT: T).isConstQualified())
1007 return false;
1008 if (T->isReferenceType())
1009 return false;
1010 if (T.isPODType(Context: C) || T->isObjCLifetimeType())
1011 return true;
1012
1013 if (const RecordType *RT = T->getAs<RecordType>())
1014 return HasNoThrowOperator(RT, Op: OO_Equal, Self, KeyLoc, C,
1015 HasTrivial: &CXXRecordDecl::hasTrivialCopyAssignment,
1016 HasNonTrivial: &CXXRecordDecl::hasNonTrivialCopyAssignment,
1017 IsDesiredOp: &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(Context: C))
1024 return true;
1025
1026 if (const RecordType *RT = C.getBaseElementType(QT: T)->getAs<RecordType>())
1027 return HasNoThrowOperator(RT, Op: OO_Equal, Self, KeyLoc, C,
1028 HasTrivial: &CXXRecordDecl::hasTrivialMoveAssignment,
1029 HasNonTrivial: &CXXRecordDecl::hasNonTrivialMoveAssignment,
1030 IsDesiredOp: &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(Context: 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(Class: 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>(Val: ND->getUnderlyingDecl()))
1052 continue;
1053 // UsingDecl itself is not a constructor
1054 if (isa<UsingDecl>(Val: ND))
1055 continue;
1056 auto *Constructor = cast<CXXConstructorDecl>(Val: ND->getUnderlyingDecl());
1057 if (Constructor->isCopyConstructor(TypeQuals&: FoundTQs)) {
1058 FoundConstructor = true;
1059 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1060 CPT = Self.ResolveExceptionSpec(Loc: KeyLoc, FPT: 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(Context: C) || T->isObjCLifetimeType())
1080 return true;
1081 if (CXXRecordDecl *RD = C.getBaseElementType(QT: T)->getAsCXXRecordDecl()) {
1082 if (RD->hasTrivialDefaultConstructor() &&
1083 !RD->hasNonTrivialDefaultConstructor())
1084 return true;
1085
1086 bool FoundConstructor = false;
1087 for (const auto *ND : Self.LookupConstructors(Class: RD)) {
1088 // FIXME: In C++0x, a constructor template can be a default constructor.
1089 if (isa<FunctionTemplateDecl>(Val: ND->getUnderlyingDecl()))
1090 continue;
1091 // UsingDecl itself is not a constructor
1092 if (isa<UsingDecl>(Val: ND))
1093 continue;
1094 auto *Constructor = cast<CXXConstructorDecl>(Val: ND->getUnderlyingDecl());
1095 if (Constructor->isDefaultConstructor()) {
1096 FoundConstructor = true;
1097 auto *CPT = Constructor->getType()->castAs<FunctionProtoType>();
1098 CPT = Self.ResolveExceptionSpec(Loc: KeyLoc, FPT: 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(Class: 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(Ty: T);
1129 case UTT_IsTriviallyRelocatable:
1130 return IsTriviallyRelocatableType(SemaRef&: Self, T);
1131 case UTT_IsBitwiseCloneable:
1132 return T.isBitwiseCloneableType(Context: C);
1133 case UTT_IsCppTriviallyRelocatable:
1134 return Self.IsCXXTriviallyRelocatableType(Type: T);
1135 case UTT_IsReplaceable:
1136 return Self.IsCXXReplaceableType(Type: T);
1137 case UTT_CanPassInRegs:
1138 if (CXXRecordDecl *RD = T->getAsCXXRecordDecl(); RD && !T.hasQualifiers())
1139 return RD->canPassInRegisters();
1140 Self.Diag(Loc: KeyLoc, DiagID: diag::err_builtin_pass_in_regs_non_class) << T;
1141 return false;
1142 case UTT_IsTriviallyEqualityComparable:
1143 return isTriviallyEqualityComparableType(S&: Self, Type: T, KeyLoc);
1144 case UTT_IsImplicitLifetime: {
1145 DiagnoseVLAInCXXTypeTrait(S&: Self, T: TInfo,
1146 TypeTraitID: tok::kw___builtin_is_implicit_lifetime);
1147 DiagnoseAtomicInCXXTypeTrait(S&: Self, T: TInfo,
1148 TypeTraitID: 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(Loc: TInfo->getTypeLoc().getBeginLoc(), T,
1182 DiagID: diag::err_incomplete_type))
1183 return false;
1184 if (DiagnoseVLAInCXXTypeTrait(S&: Self, T: TInfo,
1185 TypeTraitID: 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(T1: T);
1196 }
1197}
1198
1199static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
1200 const TypeSourceInfo *Lhs,
1201 const TypeSourceInfo *Rhs,
1202 SourceLocation KeyLoc);
1203
1204static 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(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT) ||
1242 Self.isAbstractType(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT))
1243 return ExprError();
1244
1245 // Compute the result of add_rvalue_reference.
1246 if (LhsT->isObjectType() || LhsT->isFunctionType())
1247 LhsT = Self.Context.getRValueReferenceType(T: LhsT);
1248
1249 // Build a fake source and destination for initialization.
1250 InitializedEntity To(InitializedEntity::InitializeTemporary(Type: RhsT));
1251 Expr *From = new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1252 OpaqueValueExpr(KeyLoc, LhsT.getNonLValueExprType(Context: Self.Context),
1253 Expr::getValueKindForType(T: LhsT));
1254 InitializationKind Kind =
1255 InitializationKind::CreateCopy(InitLoc: KeyLoc, EqualLoc: 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(S&: Self, Entity: To, Kind, Args: From);
1268 if (Result.isInvalid() || SFINAE.hasErrorOccurred())
1269 return ExprError();
1270
1271 return Result;
1272}
1273
1274static 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(DecompType: T, Loc: ArgRange.getBegin());
1288 if (!Size) {
1289 S.Diag(Loc: KWLoc, DiagID: diag::err_arg_is_not_destructurable) << T << ArgRange;
1290 return APValue();
1291 }
1292 return APValue(
1293 S.getASTContext().MakeIntValue(Value: *Size, Type: S.getASTContext().getSizeType()));
1294 break;
1295 }
1296 default:
1297 llvm_unreachable("Not a SizeT type trait");
1298 }
1299}
1300
1301static 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(Self&: S, UTT: Kind, KeyLoc: KWLoc, TInfo: 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(Self&: S, BTT: Kind, Lhs: Args[0], Rhs: Args[1], KeyLoc: 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 Loc: KWLoc, T: ArgTy, DiagID: 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(N: 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(T: ArgTy);
1380 ArgExprs.push_back(
1381 Elt: new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
1382 OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
1383 ArgTy.getNonLValueExprType(Context: S.Context),
1384 Expr::getValueKindForType(T: 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(Context&: S.Context, TypeInfo: Args[0]));
1395 InitializationKind InitKind(
1396 Kind == clang::BTT_ReferenceConvertsFromTemporary
1397 ? InitializationKind::CreateCopy(InitLoc: KWLoc, EqualLoc: KWLoc)
1398 : InitializationKind::CreateDirect(InitLoc: KWLoc, LParenLoc: KWLoc, RParenLoc));
1399 InitializationSequence Init(S, To, InitKind, ArgExprs);
1400 if (Init.Failed())
1401 return false;
1402
1403 ExprResult Result = Init.Perform(S, Entity: To, Kind: InitKind, Args: 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 T: S.Context.getPointerType(T: T.getNonReferenceType()));
1432 TypeSourceInfo *UPtr = S.Context.CreateTypeSourceInfo(
1433 T: S.Context.getPointerType(T: U.getNonReferenceType()));
1434 return !CheckConvertibilityForTypeTraits(Self&: S, Lhs: UPtr, Rhs: TPtr, KeyLoc: RParenLoc,
1435 OpaqueExprAllocator)
1436 .isInvalid();
1437 }
1438
1439 if (Kind == clang::TT_IsNothrowConstructible)
1440 return S.canThrow(E: 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(Ctx: 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
1463namespace {
1464void 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(Loc: KWLoc, DiagID: diag::warn_deprecated_builtin)
1499 << getTraitSpelling(T: Kind) << getTraitSpelling(T: Replacement);
1500}
1501} // namespace
1502
1503bool Sema::CheckTypeTraitArity(unsigned Arity, SourceLocation Loc, size_t N) {
1504 if (Arity && N != Arity) {
1505 Diag(Loc, DiagID: 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, DiagID: diag::err_type_trait_arity)
1512 << 1 << 1 << 1 << (int)N << SourceRange(Loc);
1513 return false;
1514 }
1515 return true;
1516}
1517
1518enum class TypeTraitReturnType {
1519 Bool,
1520 SizeT,
1521};
1522
1523static TypeTraitReturnType GetReturnType(TypeTrait Kind) {
1524 if (Kind == TypeTrait::UTT_StructuredBindingSize)
1525 return TypeTraitReturnType::SizeT;
1526 return TypeTraitReturnType::Bool;
1527}
1528
1529ExprResult Sema::BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
1530 ArrayRef<TypeSourceInfo *> Args,
1531 SourceLocation RParenLoc) {
1532 if (!CheckTypeTraitArity(Arity: getTypeTraitArity(T: Kind), Loc: KWLoc, N: Args.size()))
1533 return ExprError();
1534
1535 if (Kind <= UTT_Last && !CheckUnaryTypeTraitTypeCompleteness(
1536 S&: *this, UTT: Kind, Loc: KWLoc, ArgTy: Args[0]->getType()))
1537 return ExprError();
1538
1539 DiagnoseBuiltinDeprecation(S&: *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(S&: *this, Kind, KWLoc, Args, RParenLoc,
1552 IsDependent: Dependent);
1553 return TypeTraitExpr::Create(C: Context, T: Context.getLogicalOperationType(),
1554 Loc: KWLoc, Kind, Args, RParenLoc, Value: Result);
1555 }
1556 case TypeTraitReturnType::SizeT: {
1557 APValue Result =
1558 EvaluateSizeTTypeTrait(S&: *this, Kind, KWLoc, Args, RParenLoc, IsDependent: Dependent);
1559 return TypeTraitExpr::Create(C: Context, T: Context.getSizeType(), Loc: KWLoc, Kind,
1560 Args, RParenLoc, Value: Result);
1561 }
1562 }
1563 llvm_unreachable("unhandled type trait return type");
1564}
1565
1566ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc,
1567 ArrayRef<ParsedType> Args,
1568 SourceLocation RParenLoc) {
1569 SmallVector<TypeSourceInfo *, 4> ConvertedArgs;
1570 ConvertedArgs.reserve(N: Args.size());
1571
1572 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
1573 TypeSourceInfo *TInfo;
1574 QualType T = GetTypeFromParser(Ty: Args[I], TInfo: &TInfo);
1575 if (!TInfo)
1576 TInfo = Context.getTrivialTypeSourceInfo(T, Loc: KWLoc);
1577
1578 ConvertedArgs.push_back(Elt: TInfo);
1579 }
1580
1581 return BuildTypeTrait(Kind, KWLoc, Args: ConvertedArgs, RParenLoc);
1582}
1583
1584bool 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(Loc: RhsTLoc, T: RhsT,
1605 DiagID: diag::err_incomplete_type_used_in_type_trait_expr))
1606 return false;
1607
1608 return BaseInterface->isSuperClassOf(I: 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(Loc: RhsTLoc, T: RhsT,
1629 DiagID: diag::err_incomplete_type_used_in_type_trait_expr))
1630 return false;
1631
1632 return cast<CXXRecordDecl>(Val: rhsRecord->getDecl())
1633 ->isDerivedFrom(Base: cast<CXXRecordDecl>(Val: lhsRecord->getDecl()));
1634}
1635
1636static 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(RhsTLoc: 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(S&: Self, T: Lhs,
1656 TypeTraitID: tok::kw___builtin_is_virtual_base_of);
1657 DiagnoseVLAInCXXTypeTrait(S&: Self, T: Rhs,
1658 TypeTraitID: 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(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT,
1670 DiagID: diag::err_incomplete_type))
1671 return false;
1672
1673 return cast<CXXRecordDecl>(Val: DerivedRecord->getDecl())
1674 ->isVirtuallyDerivedFrom(Base: cast<CXXRecordDecl>(Val: BaseRecord->getDecl()));
1675 }
1676 case BTT_IsSame:
1677 return Self.Context.hasSameType(T1: LhsT, T2: 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(T: LhsT, Quals&: LhsQuals);
1682 QualType Rhs = Self.getASTContext().getUnqualifiedArrayType(T: RhsT, Quals&: RhsQuals);
1683 return Self.Context.typesAreCompatible(T1: Lhs, T2: 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(E: 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 Loc: Lhs->getTypeLoc().getBeginLoc(), T: LhsT,
1719 DiagID: diag::err_incomplete_type_used_in_type_trait_expr))
1720 return false;
1721 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1722 Self.RequireCompleteType(
1723 Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT,
1724 DiagID: 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(T: Ty);
1736 return {KeyLoc, Ty.getNonLValueExprType(Context: Self.Context),
1737 Expr::getValueKindForType(T: 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, OpLoc: KeyLoc, Opc: BO_Assign, LHSExpr: &Lhs, RHSExpr: &Rhs);
1751 if (Result.isInvalid())
1752 return false;
1753
1754 // Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
1755 Self.CheckUnusedVolatileAssignment(E: 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(E: 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(T: LhsT) ||
1773 Context.containsAddressDiscriminatedPointerAuth(T: RhsT))
1774 return false;
1775 return !Result.get()->hasNonTrivialCall(Ctx: 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(Loc: Lhs->getTypeLoc().getBeginLoc(), T: LhsT,
1784 DiagID: diag::err_incomplete_type);
1785 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType())
1786 Self.RequireCompleteType(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT,
1787 DiagID: diag::err_incomplete_type);
1788
1789 DiagnoseVLAInCXXTypeTrait(S&: Self, T: Lhs, TypeTraitID: tok::kw___is_layout_compatible);
1790 DiagnoseVLAInCXXTypeTrait(S&: Self, T: Rhs, TypeTraitID: tok::kw___is_layout_compatible);
1791
1792 return Self.IsLayoutCompatible(T1: LhsT, T2: RhsT);
1793 }
1794 case BTT_IsPointerInterconvertibleBaseOf: {
1795 if (LhsT->isStructureOrClassType() && RhsT->isStructureOrClassType() &&
1796 !Self.getASTContext().hasSameUnqualifiedType(T1: LhsT, T2: RhsT)) {
1797 Self.RequireCompleteType(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT,
1798 DiagID: diag::err_incomplete_type);
1799 }
1800
1801 DiagnoseVLAInCXXTypeTrait(S&: Self, T: Lhs,
1802 TypeTraitID: tok::kw___is_pointer_interconvertible_base_of);
1803 DiagnoseVLAInCXXTypeTrait(S&: Self, T: Rhs,
1804 TypeTraitID: tok::kw___is_pointer_interconvertible_base_of);
1805
1806 return Self.IsPointerInterconvertibleBaseOf(Base: Lhs, Derived: Rhs);
1807 }
1808 case BTT_IsDeducible: {
1809 const auto *TSTToBeDeduced = cast<DeducedTemplateSpecializationType>(Val&: LhsT);
1810 sema::TemplateDeductionInfo Info(KeyLoc);
1811 return Self.DeduceTemplateArgumentsFromType(
1812 TD: TSTToBeDeduced->getTemplateName().getAsTemplateDecl(), FromType: RhsT,
1813 Info) == TemplateDeductionResult::Success;
1814 }
1815 case BTT_IsScalarizedLayoutCompatible: {
1816 if (!LhsT->isVoidType() && !LhsT->isIncompleteArrayType() &&
1817 Self.RequireCompleteType(Loc: Lhs->getTypeLoc().getBeginLoc(), T: LhsT,
1818 DiagID: diag::err_incomplete_type))
1819 return true;
1820 if (!RhsT->isVoidType() && !RhsT->isIncompleteArrayType() &&
1821 Self.RequireCompleteType(Loc: Rhs->getTypeLoc().getBeginLoc(), T: RhsT,
1822 DiagID: diag::err_incomplete_type))
1823 return true;
1824
1825 DiagnoseVLAInCXXTypeTrait(
1826 S&: Self, T: Lhs, TypeTraitID: tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1827 DiagnoseVLAInCXXTypeTrait(
1828 S&: Self, T: Rhs, TypeTraitID: tok::kw___builtin_hlsl_is_scalarized_layout_compatible);
1829
1830 return Self.HLSL().IsScalarizedLayoutCompatible(T1: LhsT, T2: RhsT);
1831 }
1832 default:
1833 llvm_unreachable("not a BTT");
1834 }
1835 llvm_unreachable("Unknown type trait or not implemented");
1836}
1837
1838ExprResult Sema::ActOnArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc,
1839 ParsedType Ty, Expr *DimExpr,
1840 SourceLocation RParen) {
1841 TypeSourceInfo *TSInfo;
1842 QualType T = GetTypeFromParser(Ty, TInfo: &TSInfo);
1843 if (!TSInfo)
1844 TSInfo = Context.getTrivialTypeSourceInfo(T);
1845
1846 return BuildArrayTypeTrait(ATT, KWLoc, TSInfo, DimExpr, RParen);
1847}
1848
1849static 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 E: DimExpr, Result: &Value, DiagID: diag::err_dimension_expr_not_constant_integer)
1871 .isInvalid())
1872 return 0;
1873 if (Value.isSigned() && Value.isNegative()) {
1874 Self.Diag(Loc: KeyLoc, DiagID: 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
1904ExprResult 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(Self&: *this, ATT, T, DimExpr, KeyLoc: 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
1924ExprResult 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(OET: ET, KWLoc, Queried, RParen);
1931
1932 return Result;
1933}
1934
1935static 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
1945ExprResult 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(E: Queried);
1951 if (PE.isInvalid())
1952 return ExprError();
1953 return BuildExpressionTrait(ET, KWLoc, Queried: PE.get(), RParen);
1954 }
1955
1956 bool Value = EvaluateExpressionTrait(ET, E: Queried);
1957
1958 return new (Context)
1959 ExpressionTraitExpr(KWLoc, ET, Queried, Value, RParen, Context.BoolTy);
1960}
1961
1962static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) {
1963 return llvm::StringSwitch<std::optional<TypeTrait>>(Name)
1964 .Case(S: "is_trivially_relocatable",
1965 Value: TypeTrait::UTT_IsCppTriviallyRelocatable)
1966 .Case(S: "is_replaceable", Value: TypeTrait::UTT_IsReplaceable)
1967 .Case(S: "is_trivially_copyable", Value: TypeTrait::UTT_IsTriviallyCopyable)
1968 .Case(S: "is_assignable", Value: TypeTrait::BTT_IsAssignable)
1969 .Case(S: "is_empty", Value: TypeTrait::UTT_IsEmpty)
1970 .Case(S: "is_standard_layout", Value: TypeTrait::UTT_IsStandardLayout)
1971 .Case(S: "is_constructible", Value: TypeTrait::TT_IsConstructible)
1972 .Default(Value: std::nullopt);
1973}
1974
1975using 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.
1982static 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>(Val: E)) {
1988 Trait = TraitExpr->getTrait();
1989 for (const auto *Arg : TraitExpr->getArgs())
1990 Args.push_back(Elt: Arg->getType());
1991 return {{Trait.value(), std::move(Args)}};
1992 }
1993 const auto *Ref = dyn_cast<DeclRefExpr>(Val: E);
1994 if (!Ref)
1995 return std::nullopt;
1996
1997 // std::is_xxx_v<>
1998 if (const auto *VD =
1999 dyn_cast<VarTemplateSpecializationDecl>(Val: Ref->getDecl())) {
2000 if (!VD->isInStdNamespace())
2001 return std::nullopt;
2002 StringRef Name = VD->getIdentifier()->getName();
2003 if (!Name.consume_back(Suffix: "_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(Elt: InnerArg.getAsType());
2012 } else if (Arg.getKind() == TemplateArgument::ArgKind::Type) {
2013 Args.push_back(Elt: 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>(Val: Ref->getDecl());
2023 Ref->hasQualifier() && VD && VD->getIdentifier()->isStr(Str: "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(Name: D->getIdentifier()->getName());
2035 if (!Trait)
2036 return std::nullopt;
2037 for (const auto &Arg : Ts->template_arguments())
2038 Args.push_back(Elt: Arg.getAsType());
2039 return {{Trait.value(), std::move(Args)}};
2040 }
2041 return std::nullopt;
2042}
2043
2044static 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, DiagID: 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 Val: LookupSpecialMemberFromXValue(SemaRef, RD: D, /*Assign=*/false));
2066 if (Decl && Decl->isUserProvided())
2067 SemaRef.Diag(Loc, DiagID: 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, RD: D, /*Assign=*/true);
2074 if (Decl && Decl->isUserProvided())
2075 SemaRef.Diag(Loc, DiagID: 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, DiagID: diag::note_unsatisfied_trait_reason)
2083 << diag::TraitNotSatisfiedReason::DeletedDtr << /*User Provided*/ 1
2084 << Dtr->getSourceRange();
2085 }
2086}
2087
2088static 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, DiagID: diag::note_unsatisfied_trait_reason)
2095 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2096 << B.getSourceRange();
2097 if (!SemaRef.IsCXXTriviallyRelocatableType(Type: B.getType()))
2098 SemaRef.Diag(Loc, DiagID: 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(Type: Field->getType()))
2105 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2106 << diag::TraitNotSatisfiedReason::NTRField << Field
2107 << Field->getType() << Field->getSourceRange();
2108 }
2109 if (D->hasDeletedDestructor())
2110 SemaRef.Diag(Loc, DiagID: 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
2119static void DiagnoseNonTriviallyRelocatableReason(Sema &SemaRef,
2120 SourceLocation Loc,
2121 QualType T) {
2122 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait)
2123 << T << diag::TraitName::TriviallyRelocatable;
2124 if (T->isVariablyModifiedType())
2125 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2126 << diag::TraitNotSatisfiedReason::VLA;
2127
2128 if (T->isReferenceType())
2129 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2130 << diag::TraitNotSatisfiedReason::Ref;
2131 T = T.getNonReferenceType();
2132
2133 if (T.hasNonTrivialObjCLifetime())
2134 SemaRef.Diag(Loc, DiagID: 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(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2145}
2146
2147static 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(Type: B.getType()))
2152 SemaRef.Diag(Loc, DiagID: 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(Type: Field->getType()))
2158 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2159 << diag::TraitNotSatisfiedReason::NonReplaceableField << Field
2160 << Field->getType() << Field->getSourceRange();
2161 }
2162 if (D->hasDeletedDestructor())
2163 SemaRef.Diag(Loc, DiagID: 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 Val: LookupSpecialMemberFromXValue(SemaRef, RD: D, /*Assign=*/false));
2170 if (Decl && Decl->isDeleted())
2171 SemaRef.Diag(Loc, DiagID: 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, RD: D, /*Assign=*/true);
2178 if (Decl && Decl->isDeleted())
2179 SemaRef.Diag(Loc, DiagID: 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
2189static void DiagnoseNonReplaceableReason(Sema &SemaRef, SourceLocation Loc,
2190 QualType T) {
2191 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait)
2192 << T << diag::TraitName::Replaceable;
2193
2194 if (T->isVariablyModifiedType())
2195 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2196 << diag::TraitNotSatisfiedReason::VLA;
2197
2198 if (T->isReferenceType())
2199 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2200 << diag::TraitNotSatisfiedReason::Ref;
2201 T = T.getNonReferenceType();
2202
2203 if (T.isConstQualified())
2204 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2205 << diag::TraitNotSatisfiedReason::Const;
2206
2207 if (T.isVolatileQualified())
2208 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2209 << diag::TraitNotSatisfiedReason::Volatile;
2210
2211 bool IsArray = T->isArrayType();
2212 T = SemaRef.getASTContext().getBaseElementType(QT: T.getUnqualifiedType());
2213
2214 if (T->isScalarType())
2215 return;
2216
2217 const CXXRecordDecl *D = T->getAsCXXRecordDecl();
2218 if (!D) {
2219 SemaRef.Diag(Loc, DiagID: 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(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2231}
2232
2233static 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, DiagID: diag::note_unsatisfied_trait_reason)
2240 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2241 << B.getSourceRange();
2242 if (!B.getType().isTriviallyCopyableType(Context: D->getASTContext())) {
2243 SemaRef.Diag(Loc, DiagID: 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(Context: Field->getASTContext()))
2250 SemaRef.Diag(Loc, DiagID: 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, DiagID: 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(FD: 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, DiagID: 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
2290static 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, DiagID: diag::note_unsatisfied_trait_reason)
2304 << diag::TraitNotSatisfiedReason::CVVoidType;
2305
2306 QualType T = Ts[0];
2307 if (T->isFunctionType())
2308 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2309 << diag::TraitNotSatisfiedReason::FunctionType;
2310
2311 if (T->isIncompleteArrayType())
2312 SemaRef.Diag(Loc, DiagID: 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(N: 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(T: ArgTy);
2326 ArgExprs.push_back(
2327 Elt: new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
2328 OpaqueValueExpr(Loc, ArgTy.getNonLValueExprType(Context: SemaRef.Context),
2329 Expr::getValueKindForType(T: 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(Type: T));
2337 InitializationKind InitKind(InitializationKind::CreateDirect(InitLoc: Loc, LParenLoc: Loc, RParenLoc: Loc));
2338 InitializationSequence Init(SemaRef, To, InitKind, ArgExprs);
2339
2340 Init.Diagnose(S&: SemaRef, Entity: To, Kind: InitKind, Args: ArgExprs);
2341 SemaRef.Diag(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2342}
2343
2344static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef,
2345 SourceLocation Loc, QualType T) {
2346 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait)
2347 << T << diag::TraitName::TriviallyCopyable;
2348
2349 if (T->isReferenceType())
2350 SemaRef.Diag(Loc, DiagID: 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(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2361}
2362
2363static 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(T: Ty);
2370 return {Loc, Ty.getNonLValueExprType(Context: SemaRef.Context),
2371 Expr::getValueKindForType(T: 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, OpLoc: Loc, Opc: BO_Assign, LHSExpr: &LHS, RHSExpr: &RHS);
2382
2383 if (!D || D->isInvalidDecl())
2384 return;
2385
2386 SemaRef.Diag(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2387}
2388
2389static 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, DiagID: diag::note_unsatisfied_trait_reason)
2397 << diag::TraitNotSatisfiedReason::NonZeroLengthField << Field
2398 << Field->getSourceRange();
2399 continue;
2400 }
2401 S.Diag(Loc, DiagID: 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, DiagID: 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, DiagID: diag::note_unsatisfied_trait_reason)
2423 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2424 << B.getSourceRange();
2425 }
2426 if (!BR->isEmpty()) {
2427 S.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2428 << diag::TraitNotSatisfiedReason::NonEmptyBase << B.getType()
2429 << B.getSourceRange();
2430 }
2431 }
2432}
2433
2434static void DiagnoseIsEmptyReason(Sema &S, SourceLocation Loc, QualType T) {
2435 // Emit primary "not empty" diagnostic.
2436 S.Diag(Loc, DiagID: 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, DiagID: 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(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2453 }
2454 }
2455}
2456
2457static 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
2475static 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, DiagID: diag::note_unsatisfied_trait_reason)
2481 << diag::TraitNotSatisfiedReason::VBase << B.getType()
2482 << B.getSourceRange();
2483 }
2484 if (!B.getType()->isStandardLayoutType()) {
2485 SemaRef.Diag(Loc, DiagID: 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, DiagID: diag::note_unsatisfied_trait_reason)
2509 << diag::TraitNotSatisfiedReason::MixedAccess;
2510
2511 SemaRef.Diag(Loc: FirstField->getLocation(), DiagID: diag::note_defined_here)
2512 << FirstField;
2513
2514 SemaRef.Diag(Loc: Field->getLocation(), DiagID: 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, DiagID: 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, DiagID: diag::note_unsatisfied_trait_reason)
2538 << diag::TraitNotSatisfiedReason::VirtualFunction << VirtualMD;
2539 SemaRef.Diag(Loc: VirtualMD->getLocation(), DiagID: diag::note_defined_here)
2540 << VirtualMD;
2541 } else {
2542 // If no virtual method, point to the record declaration itself.
2543 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2544 << diag::TraitNotSatisfiedReason::VirtualFunction << D;
2545 SemaRef.Diag(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2546 }
2547 }
2548 for (const FieldDecl *Field : D->fields()) {
2549 if (!Field->getType()->isStandardLayoutType()) {
2550 SemaRef.Diag(Loc, DiagID: 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(BaseMatches: [&](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, DiagID: diag::note_unsatisfied_trait_reason)
2567 << diag::TraitNotSatisfiedReason::IndirectBaseWithFields << Indirect
2568 << Indirect->getSourceRange();
2569 }
2570 }
2571}
2572
2573static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc,
2574 QualType T) {
2575 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait)
2576 << T << diag::TraitName::StandardLayout;
2577
2578 // Check type-level exclusion first.
2579 if (T->isVariablyModifiedType()) {
2580 SemaRef.Diag(Loc, DiagID: diag::note_unsatisfied_trait_reason)
2581 << diag::TraitNotSatisfiedReason::VLA;
2582 return;
2583 }
2584
2585 if (T->isReferenceType()) {
2586 SemaRef.Diag(Loc, DiagID: 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(Loc: D->getLocation(), DiagID: diag::note_defined_here) << D;
2599}
2600
2601void 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(SemaRef&: *this, Loc: E->getBeginLoc(), T: Args[0]);
2614 break;
2615 case UTT_IsReplaceable:
2616 DiagnoseNonReplaceableReason(SemaRef&: *this, Loc: E->getBeginLoc(), T: Args[0]);
2617 break;
2618 case UTT_IsTriviallyCopyable:
2619 DiagnoseNonTriviallyCopyableReason(SemaRef&: *this, Loc: E->getBeginLoc(), T: Args[0]);
2620 break;
2621 case BTT_IsAssignable:
2622 DiagnoseNonAssignableReason(SemaRef&: *this, Loc: E->getBeginLoc(), T: Args[0], U: Args[1]);
2623 break;
2624 case UTT_IsEmpty:
2625 DiagnoseIsEmptyReason(S&: *this, Loc: E->getBeginLoc(), T: Args[0]);
2626 break;
2627 case UTT_IsStandardLayout:
2628 DiagnoseNonStandardLayoutReason(SemaRef&: *this, Loc: E->getBeginLoc(), T: Args[0]);
2629 break;
2630 case TT_IsConstructible:
2631 DiagnoseNonConstructibleReason(SemaRef&: *this, Loc: E->getBeginLoc(), Ts: Args);
2632 break;
2633 default:
2634 break;
2635 }
2636}
2637

source code of clang/lib/Sema/SemaTypeTraits.cpp