48 changes: 46 additions & 2 deletions clang/lib/AST/DeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
HasTrivialSpecialMembersForCall(SMF_All),
DeclaredNonTrivialSpecialMembers(0),
DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true),
DeclaredNonTrivialSpecialMembersForCall(0),
IsNaturallyTriviallyRelocatable(true),
HasNonTriviallyRelocatableSubobject(false), HasIrrelevantDestructor(true),
HasConstexprNonCopyMoveConstructor(false),
HasDefaultedDefaultConstructor(false),
DefaultedDefaultConstructorIsConstexpr(true),
Expand Down Expand Up @@ -279,6 +281,11 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,

// An aggregate is a class with [...] no virtual functions.
data().Aggregate = false;

// A trivially relocatable class is a class:
// -- which has no virtual member functions or virtual base classes
data().IsNaturallyTriviallyRelocatable = false;
data().HasNonTriviallyRelocatableSubobject = true;
}

// C++0x [class]p7:
Expand All @@ -293,6 +300,11 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C))
data().HasNonLiteralTypeFieldsOrBases = true;

if (Base->isVirtual() || !BaseClassDecl->isTriviallyRelocatable()) {
data().IsNaturallyTriviallyRelocatable = false;
data().HasNonTriviallyRelocatableSubobject = true;
}

// Now go through all virtual bases of this base and add them.
for (const auto &VBase : BaseClassDecl->vbases()) {
// Add this base if it's not already in the list.
Expand Down Expand Up @@ -611,6 +623,13 @@ bool CXXRecordDecl::hasAnyDependentBases() const {
return !forallBases([](const CXXRecordDecl *) { return true; });
}

bool CXXRecordDecl::isTriviallyRelocatable() const {
return (data().IsNaturallyTriviallyRelocatable ||
hasAttr<TriviallyRelocatableAttr>() || hasAttr<TrivialABIAttr>() ||
(hasAttr<MaybeTriviallyRelocatableAttr>() &&
!data().HasNonTriviallyRelocatableSubobject));
}

bool CXXRecordDecl::isTriviallyCopyable() const {
// C++0x [class]p5:
// A trivially copyable class is a class that:
Expand Down Expand Up @@ -802,6 +821,11 @@ void CXXRecordDecl::addedMember(Decl *D) {
// -- has no virtual functions
data().IsStandardLayout = false;
data().IsCXX11StandardLayout = false;

// A trivially relocatable class is a class:
// -- which has no virtual member functions or virtual base classes
data().IsNaturallyTriviallyRelocatable = false;
data().HasNonTriviallyRelocatableSubobject = true;
}
}

Expand Down Expand Up @@ -1113,6 +1137,14 @@ void CXXRecordDecl::addedMember(Decl *D) {
} else if (!T.isCXX98PODType(Context))
data().PlainOldData = false;

// A trivially relocatable class is a class:
// -- all of whose members are either of reference type or of trivially
// relocatable type
if (!T->isReferenceType() && !T.isTriviallyRelocatableType(Context)) {
data().IsNaturallyTriviallyRelocatable = false;
data().HasNonTriviallyRelocatableSubobject = true;
}

if (T->isReferenceType()) {
if (!Field->hasInClassInitializer())
data().HasUninitializedReferenceMember = true;
Expand Down Expand Up @@ -1489,8 +1521,9 @@ void CXXRecordDecl::addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD,
// See https://github.com/llvm/llvm-project/issues/59206

if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD)) {
if (DD->isUserProvided())
if (DD->isUserProvided()) {
data().HasIrrelevantDestructor = false;
}
// If the destructor is explicitly defaulted and not trivial or not public
// or if the destructor is deleted, we clear HasIrrelevantDestructor in
// finishedDefaultedOrDeletedMember.
Expand All @@ -1506,6 +1539,17 @@ void CXXRecordDecl::addedEligibleSpecialMemberFunction(const CXXMethodDecl *MD,
data().IsAnyDestructorNoReturn = true;
}

// A trivially relocatable class is a class:
// -- where no eligible copy constructor, move constructor, copy
// assignment operator, move assignment operator, or destructor is
// user-provided,
if (MD->isUserProvided() &&
(SMKind & (SMF_CopyConstructor | SMF_MoveConstructor |
SMF_CopyAssignment | SMF_MoveAssignment | SMF_Destructor)) !=
0u) {
data().IsNaturallyTriviallyRelocatable = false;
}

if (!MD->isImplicit() && !MD->isUserProvided()) {
// This method is user-declared but not user-provided. We can't work
// out whether it's trivial yet (not until we get to the end of the
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/JSONNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ JSONNodeDumper::createCXXRecordDefinitionData(const CXXRecordDecl *RD) {
FIELD1(isAggregate);
FIELD1(isStandardLayout);
FIELD1(isTriviallyCopyable);
FIELD1(isTriviallyRelocatable);
FIELD1(isPOD);
FIELD1(isTrivial);
FIELD1(isPolymorphic);
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/AST/ParentMapContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@

using namespace clang;

ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}

ParentMapContext::~ParentMapContext() = default;

void ParentMapContext::clear() { Parents.reset(); }

const Expr *ParentMapContext::traverseIgnored(const Expr *E) const {
return traverseIgnored(const_cast<Expr *>(E));
}
Expand Down Expand Up @@ -482,3 +476,9 @@ DynTypedNodeList ParentMapContext::getParents(const DynTypedNode &Node) {
Parents = std::make_unique<ParentMap>(ASTCtx);
return Parents->getParents(getTraversalKind(), Node);
}

ParentMapContext::ParentMapContext(ASTContext &Ctx) : ASTCtx(Ctx) {}

ParentMapContext::~ParentMapContext() = default;

void ParentMapContext::clear() { Parents.reset(); }
1 change: 1 addition & 0 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2483,6 +2483,7 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
FLAG(isAggregate, aggregate);
FLAG(isStandardLayout, standard_layout);
FLAG(isTriviallyCopyable, trivially_copyable);
FLAG(isTriviallyRelocatable, trivially_relocatable);
FLAG(isPOD, pod);
FLAG(isTrivial, trivial);
FLAG(isPolymorphic, polymorphic);
Expand Down
12 changes: 6 additions & 6 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2837,22 +2837,22 @@ bool QualType::isTriviallyCopyConstructibleType(

bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
QualType BaseElementType = Context.getBaseElementType(*this);

if (BaseElementType->isIncompleteType()) {
return false;
} else if (!BaseElementType->isObjectType()) {
return false;
} else if (const auto *RD = BaseElementType->getAsRecordDecl()) {
return RD->canPassInRegisters();
} else if (CXXRecordDecl *RD = BaseElementType->getAsCXXRecordDecl()) {
return RD->isTriviallyRelocatable();
} else if (BaseElementType.isTriviallyCopyableType(Context)) {
return true;
} else {
switch (isNonTrivialToPrimitiveDestructiveMove()) {
case PCK_Trivial:
return !isDestructedType();
case PCK_ARCStrong:
case PCK_Trivial:
case PCK_VolatileTrivial:
return true;
default:
case PCK_ARCWeak:
case PCK_Struct:
return false;
}
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,

ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const {
return llvm::ArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin -
Builtin::FirstTSBuiltin);
unsigned(Builtin::FirstTSBuiltin));
}

std::optional<std::pair<unsigned, unsigned>>
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/Hexagon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,5 @@ void HexagonTargetInfo::fillValidCPUList(

ArrayRef<Builtin::Info> HexagonTargetInfo::getTargetBuiltins() const {
return llvm::ArrayRef(BuiltinInfo, clang::Hexagon::LastTSBuiltin -
Builtin::FirstTSBuiltin);
unsigned(Builtin::FirstTSBuiltin));
}
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ bool LoongArchTargetInfo::hasFeature(StringRef Feature) const {

ArrayRef<Builtin::Info> LoongArchTargetInfo::getTargetBuiltins() const {
return llvm::ArrayRef(BuiltinInfo, clang::LoongArch::LastTSBuiltin -
Builtin::FirstTSBuiltin);
unsigned(Builtin::FirstTSBuiltin));
}

bool LoongArchTargetInfo::handleTargetFeatures(
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Basic/Targets/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ bool WebAssemblyTargetInfo::handleTargetFeatures(

ArrayRef<Builtin::Info> WebAssemblyTargetInfo::getTargetBuiltins() const {
return llvm::ArrayRef(BuiltinInfo, clang::WebAssembly::LastTSBuiltin -
Builtin::FirstTSBuiltin);
unsigned(Builtin::FirstTSBuiltin));
}

void WebAssemblyTargetInfo::adjust(DiagnosticsEngine &Diags,
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Basic/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ static void EmitUnknownDiagWarning(DiagnosticsEngine &Diags,
StringRef Suggestion = DiagnosticIDs::getNearestOption(Flavor, Opt);
Diags.Report(diag::warn_unknown_diag_option)
<< (Flavor == diag::Flavor::WarningOrError ? 0 : 1)
<< (Prefix.str() += std::string(Opt)) << !Suggestion.empty()
<< (Prefix.str() += std::string(Suggestion));
<< (Prefix.str() + std::string(Opt)) << !Suggestion.empty()
<< (Prefix.str() + std::string(Suggestion));
}

void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5101,7 +5101,7 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
pushLifetimeExtendedDestroy(getCleanupKind(DtorKind), DeclPtr,
E->getType(), getDestroyer(DtorKind),
DtorKind & EHCleanup);
unsigned(DtorKind) & EHCleanup);

return Result;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ AggExprEmitter::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
if (QualType::DestructionKind DtorKind = E->getType().isDestructedType())
CGF.pushLifetimeExtendedDestroy(
CGF.getCleanupKind(DtorKind), Slot.getAddress(), E->getType(),
CGF.getDestroyer(DtorKind), DtorKind & EHCleanup);
CGF.getDestroyer(DtorKind), unsigned(DtorKind) & EHCleanup);
}

/// Attempt to look through various unimportant expressions to find a
Expand Down
22 changes: 19 additions & 3 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef<const Attr *> Attrs) {
case Stmt::DoStmtClass: EmitDoStmt(cast<DoStmt>(*S), Attrs); break;
case Stmt::ForStmtClass: EmitForStmt(cast<ForStmt>(*S), Attrs); break;

case Stmt::ReturnStmtClass: EmitReturnStmt(cast<ReturnStmt>(*S)); break;
case Stmt::ReturnStmtClass:
EmitReturnStmt(cast<ReturnStmt>(*S), Attrs);
break;

case Stmt::SwitchStmtClass: EmitSwitchStmt(cast<SwitchStmt>(*S)); break;
case Stmt::GCCAsmStmtClass: // Intentional fall-through.
Expand Down Expand Up @@ -1478,7 +1480,8 @@ static bool isSwiftAsyncCallee(const CallExpr *CE) {
/// EmitReturnStmt - Note that due to GCC extensions, this can have an operand
/// if the function returns void, or may be missing one if the function returns
/// non-void. Fun stuff :).
void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S,
ArrayRef<const Attr *> Attrs) {
if (requiresReturnValueCheck()) {
llvm::Constant *SLoc = EmitCheckSourceLocation(S.getBeginLoc());
auto *SLocPtr =
Expand Down Expand Up @@ -1508,6 +1511,7 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
// rules about not jumping to statements following block literals with
// non-trivial cleanups.
SaveRetExprRAII SaveRetExpr(RV, *this);
bool DidApplyNRVO = false;

RunCleanupsScope cleanupScope(*this);
if (const auto *EWC = dyn_cast_or_null<ExprWithCleanups>(RV))
Expand Down Expand Up @@ -1540,8 +1544,10 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {

// If there is an NRVO flag for this variable, set it to 1 into indicate
// that the cleanup code should not destroy the variable.
if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()])
if (llvm::Value *NRVOFlag = NRVOFlags[S.getNRVOCandidate()]) {
Builder.CreateFlagStore(Builder.getTrue(), NRVOFlag);
DidApplyNRVO = true;
}
} else if (!ReturnValue.isValid() || (RV && RV->getType()->isVoidType())) {
// Make sure not to return anything, but evaluate the expression
// for side effects.
Expand Down Expand Up @@ -1581,6 +1587,16 @@ void CodeGenFunction::EmitReturnStmt(const ReturnStmt &S) {
}
}

if (!DidApplyNRVO) {
for (const Attr *A : Attrs) {
if (A->getKind() == attr::MustNrvo) {
CGM.getDiags().Report(A->getLocation(),
diag::warn_mustnrvo_failed_to_elide)
<< A << A->getRange();
}
}
}

++NumReturnExprs;
if (!RV || RV->isEvaluatable(getContext()))
++NumSimpleReturnExprs;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3558,7 +3558,7 @@ class CodeGenFunction : public CodeGenTypeCache {
void EmitWhileStmt(const WhileStmt &S, ArrayRef<const Attr *> Attrs = {});
void EmitDoStmt(const DoStmt &S, ArrayRef<const Attr *> Attrs = {});
void EmitForStmt(const ForStmt &S, ArrayRef<const Attr *> Attrs = {});
void EmitReturnStmt(const ReturnStmt &S);
void EmitReturnStmt(const ReturnStmt &S, ArrayRef<const Attr *> Attrs = {});
void EmitDeclStmt(const DeclStmt &S);
void EmitBreakStmt(const BreakStmt &S);
void EmitContinueStmt(const ContinueStmt &S);
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7158,6 +7158,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_access_control);
Args.addOptOutFlag(CmdArgs, options::OPT_felide_constructors,
options::OPT_fno_elide_constructors);
Args.addOptOutFlag(CmdArgs, options::OPT_fp3279_trivially_fooable,
options::OPT_fno_p3279_trivially_fooable);

ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Frontend/InitPreprocessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
Builder.defineMacro("__cpp_static_call_operator", "202207L");
Builder.defineMacro("__cpp_named_character_escapes", "202207L");
Builder.defineMacro("__cpp_placeholder_variables", "202306L");
Builder.defineMacro("__cpp_impl_trivially_relocatable", "202401L");

// C++26 features supported in earlier language modes.
Builder.defineMacro("__cpp_pack_indexing", "202311L");
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4711,6 +4711,7 @@ static bool IsBuiltInOrStandardCXX11Attribute(IdentifierInfo *AttrName,
case ParsedAttr::AT_FallThrough:
case ParsedAttr::AT_CXX11NoReturn:
case ParsedAttr::AT_NoUniqueAddress:
case ParsedAttr::AT_TriviallyRelocatable:
case ParsedAttr::AT_Likely:
case ParsedAttr::AT_Unlikely:
return true;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6308,7 +6308,7 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args,
*this, OrigFormatExpr, Args, APK, format_idx, firstDataArg, Type,
CallType,
/*IsFunctionCall*/ true, CheckedVarArgs, UncoveredArg,
/*no string offset*/ llvm::APSInt(64, false) = 0);
/*no string offset*/ llvm::APSInt(64, false).withValue(0));

// Generate a diagnostic where an uncovered argument is detected.
if (UncoveredArg.hasUncoveredArg()) {
Expand Down
45 changes: 45 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5786,6 +5786,44 @@ static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
}

#if 0
template<class AttrType>
static void checkAttributeNotOnFirstDecl(Sema &S, Decl *D, const ParsedAttr &AL) {
Decl *FirstD = D->getCanonicalDecl();
if (FirstD != D && !FirstD->hasAttr<AttrType>()) {
NamedDecl *ND = dyn_cast<NamedDecl>(D);
S.Diag(AL.getLoc(), diag::err_attribute_missing_on_first_decl)
<< AL.getName();
S.Diag(FirstD->getLocation(), diag::note_previous_declaration);
}
}
#endif

static void handleTriviallyRelocatableAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
// checkAttributeNotOnFirstDecl<TriviallyRelocatableAttr>(S, D, AL);

Expr *Cond = nullptr;
if (AL.getNumArgs() == 1) {
Cond = AL.getArgAsExpr(0);
if (!Cond->isTypeDependent()) {
ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
if (Converted.isInvalid()) {
return;
}
Cond = Converted.get();
}
}

D->addAttr(::new (S.Context) TriviallyRelocatableAttr(S.Context, AL, Cond));
}

static void handleMaybeTriviallyRelocatableAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
// checkAttributeNotOnFirstDecl<MaybeTriviallyRelocatableAttr>(S, D, AL);
handleSimpleAttribute<MaybeTriviallyRelocatableAttr>(S, D, AL);
}

DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
const AttributeCommonInfo &CI) {
if (D->hasAttr<DLLExportAttr>()) {
Expand Down Expand Up @@ -7272,6 +7310,13 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
handlePatchableFunctionEntryAttr(S, D, AL);
break;

case ParsedAttr::AT_TriviallyRelocatable:
handleTriviallyRelocatableAttr(S, D, AL);
break;
case ParsedAttr::AT_MaybeTriviallyRelocatable:
handleMaybeTriviallyRelocatableAttr(S, D, AL);
break;

case ParsedAttr::AT_AlwaysDestroy:
case ParsedAttr::AT_NoDestroy:
handleDestroyAttr(S, D, AL);
Expand Down
52 changes: 51 additions & 1 deletion clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7183,6 +7183,51 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
else if (Record->hasAttr<CUDADeviceBuiltinTextureTypeAttr>())
checkCUDADeviceBuiltinTextureClassTemplate(*this, Record);
}

if (!Record->isDependentContext()) {
// Deal with [[trivially_relocatable(condition)]].
if (auto *TRA = Record->getAttr<TriviallyRelocatableAttr>()) {
if (Expr *Arg = TRA->getCond()) {
// Evaluate the condition. If it's ill-formed, ignore the attribute.
// If it's well-formed and true, render this type trivially relocatable.
SFINAETrap Trap(*this);
bool Result = false;
if (!Arg->EvaluateAsBooleanCondition(Result, Context) || !Result) {
// An ill-formed, non-constant, non-boolean, or false expression drops
// the attribute.
Record->dropAttr<TriviallyRelocatableAttr>();
}
}
}

// Warn if a [[trivially_relocatable]] type isn't move-constructible
// or isn't destructible. That would be unusual, but isn't fatal.

if ((Record->hasAttr<TriviallyRelocatableAttr>() ||
Record->hasAttr<MaybeTriviallyRelocatableAttr>()) &&
!isTemplateInstantiation(Record->getTemplateSpecializationKind())) {
int Reason = 0;
SpecialMemberOverloadResult SMOR = LookupSpecialMember(
Record, CXXSpecialMemberKind::Destructor, false, false, false, false, false);
if (SMOR.getKind() != SpecialMemberOverloadResult::Success) {
Reason = 1;
} else {
SMOR = LookupSpecialMember(Record, CXXSpecialMemberKind::MoveConstructor, false,
false, false, false, false);
if (SMOR.getKind() != SpecialMemberOverloadResult::Success)
Reason = 2;
}

if (Reason != 0) {
if (Record->hasAttr<TriviallyRelocatableAttr>()) {
Diag(Record->getLocation(),
diag::warn_trivially_relocatable_class_is_not_relocatable)
<< llvm::to_underlying(Record->getCanonicalDecl()->getTagKind())
<< Context.getRecordType(Record) << (Reason == 1);
}
}
}
}
}

/// Look up the special member function that would be called by a special
Expand Down Expand Up @@ -7626,7 +7671,7 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
HadError = true;
}

// A defaulted special member cannot have cv-qualifiers.
// A defaulted special member cannot have cv-qualifiers nor an rvalue-ref-qualifier.
if (ThisType.isConstQualified() || ThisType.isVolatileQualified()) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
Expand Down Expand Up @@ -7660,6 +7705,11 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
HadError = true;
}
}
if (!HadError && MD->getFunctionObjectParameterReferenceType()->isRValueReferenceType()) {
Diag(MD->getLocation(), diag::err_defaulted_special_member_rref_qual)
<< (CSM == CXXSpecialMemberKind::MoveAssignment);
HadError = true;
}
}

// Check for parameter type matching.
Expand Down
194 changes: 163 additions & 31 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5163,13 +5163,14 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
return false;
}

static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
const CXXRecordDecl *Decl,
static bool HasNonDeletedDefaultedEqualityComparison(Sema &S, QualType Type,
SourceLocation KeyLoc) {
if (Decl->isUnion())
return false;
if (Decl->isLambda())
return Decl->isCapturelessLambda();
if (const auto *Decl = Type->getAsCXXRecordDecl()) {
if (Decl->isUnion())
return false;
if (Decl->isLambda())
return Decl->isCapturelessLambda();
}

{
EnterExpressionEvaluationContext UnevaluatedContext(
Expand All @@ -5180,7 +5181,7 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
// const ClassT& obj;
OpaqueValueExpr Operand(
KeyLoc,
Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
Type->getCanonicalTypeUnqualified().withConst(),
ExprValueKind::VK_LValue);
UnresolvedSet<16> Functions;
// obj == obj;
Expand All @@ -5193,47 +5194,49 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,

const auto *CallExpr = dyn_cast<CXXOperatorCallExpr>(Result.get());
if (!CallExpr)
return false;
return Type->isEnumeralType();
const auto *Callee = CallExpr->getDirectCallee();
auto ParamT = Callee->getParamDecl(0)->getType();
if (!Callee->isDefaulted())
return false;
if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())
if (!ParamT->isReferenceType() && !Type.isTriviallyCopyableType(S.Context))
return false;
if (ParamT.getNonReferenceType()->getUnqualifiedDesugaredType() !=
Decl->getTypeForDecl())
Type->getUnqualifiedDesugaredType())
return false;
}

return llvm::all_of(Decl->bases(),
[&](const CXXBaseSpecifier &BS) {
if (const auto *RD = BS.getType()->getAsCXXRecordDecl())
if (const auto *Decl = Type->getAsCXXRecordDecl()) {
return llvm::all_of(Decl->bases(),
[&](const CXXBaseSpecifier &BS) {
return HasNonDeletedDefaultedEqualityComparison(
S, RD, KeyLoc);
return true;
}) &&
llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
auto Type = FD->getType();
if (Type->isArrayType())
Type = Type->getBaseElementTypeUnsafe()
->getCanonicalTypeUnqualified();

if (Type->isReferenceType() || Type->isEnumeralType())
return false;
if (const auto *RD = Type->getAsCXXRecordDecl())
return HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc);
return true;
});
S, BS.getType(), KeyLoc);
}) &&
llvm::all_of(Decl->fields(), [&](const FieldDecl *FD) {
auto Type = FD->getType();
if (Type->isArrayType())
Type = Type->getBaseElementTypeUnsafe()
->getCanonicalTypeUnqualified();

if (Type->isReferenceType())
return false;
if (Type->isOverloadableType())
return HasNonDeletedDefaultedEqualityComparison(S, Type, KeyLoc);
return true;
});
}

return true;
}

static bool isTriviallyEqualityComparableType(Sema &S, QualType Type, SourceLocation KeyLoc) {
QualType CanonicalType = Type.getCanonicalType();
if (CanonicalType->isIncompleteType() || CanonicalType->isDependentType() ||
CanonicalType->isEnumeralType() || CanonicalType->isArrayType())
CanonicalType->isArrayType())
return false;

if (const auto *RD = CanonicalType->getAsCXXRecordDecl()) {
if (!HasNonDeletedDefaultedEqualityComparison(S, RD, KeyLoc))
if (CanonicalType->isOverloadableType()) {
if (!HasNonDeletedDefaultedEqualityComparison(S, CanonicalType, KeyLoc))
return false;
}

Expand Down Expand Up @@ -5800,6 +5803,119 @@ static ExprResult CheckConvertibilityForTypeTraits(
return Result;
}

static bool IsP3279TriviallyConstructibleFrom(Sema &S,
SourceLocation KWLoc,
ArrayRef<TypeSourceInfo *> Args,
SourceLocation RParenLoc)
{
assert(Args.size() == 2);
QualType TheType = Args[0]->getType().getNonReferenceType();

llvm::BumpPtrAllocator OpaqueExprAllocator;
SmallVector<Expr *, 2> ArgExprs;
ArgExprs.reserve(Args.size() - 1);
for (unsigned I = 1, N = Args.size(); I != N; ++I) {
QualType ArgTy = Args[I]->getType();
if (ArgTy->isObjectType() || ArgTy->isFunctionType())
ArgTy = S.Context.getRValueReferenceType(ArgTy);
ArgExprs.push_back(
new (OpaqueExprAllocator.Allocate<OpaqueValueExpr>())
OpaqueValueExpr(Args[I]->getTypeLoc().getBeginLoc(),
ArgTy.getNonLValueExprType(S.Context),
Expr::getValueKindForType(ArgTy)));
}

// Perform the initialization in an unevaluated context within a SFINAE
// trap at translation unit scope.
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::Unevaluated);
Sema::SFINAETrap SFINAE(S, /*AccessCheckingSFINAE=*/true);
Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
InitializedEntity To(
InitializedEntity::InitializeTemporary(S.Context, Args[0]));
InitializationKind InitKind(
InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc));
InitializationSequence Init(S, To, InitKind, ArgExprs);
if (Init.Failed())
return false;

ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
if (Result.isInvalid() || SFINAE.hasErrorOccurred())
return false;

// Under Objective-C ARC and Weak, if the destination has non-trivial
// Objective-C lifetime, this is a non-trivial construction.
if (TheType.hasNonTrivialObjCLifetime())
return false;

// For now, don't advertise even `__is_trivially_constructible(int, unsigned)`.
if (!S.Context.hasSameType(Args[1]->getType().getNonReferenceType(), TheType))
return false;

if (const auto *CE = dyn_cast<CXXConstructExpr>(Result.get())) {
if (const CXXConstructorDecl *Callee = CE->getConstructor()) {
// A constructor can be trivial only if it is defaulted; make sure it's a move or copy constructor
// of this type itself.
return (Callee->isTrivial() && !S.Context.hasSameType(Callee->getParamDecl(0)->getType().getNonReferenceType(), TheType));
}
// Is this possible? I don't think so.
assert(false);
return false;
}

// It must be a primitive type or a reference, right?
return true;
}

static bool IsP3279TriviallyAssignableFrom(Sema &Self, SourceLocation KeyLoc, QualType LhsT, QualType RhsT)
{
// Build expressions that emulate the effect of declval<T>() and
// declval<U>().
if (LhsT->isObjectType() || LhsT->isFunctionType())
LhsT = Self.Context.getRValueReferenceType(LhsT);
if (RhsT->isObjectType() || RhsT->isFunctionType())
RhsT = Self.Context.getRValueReferenceType(RhsT);
OpaqueValueExpr Lhs(KeyLoc, LhsT.getNonLValueExprType(Self.Context),
Expr::getValueKindForType(LhsT));
OpaqueValueExpr Rhs(KeyLoc, RhsT.getNonLValueExprType(Self.Context),
Expr::getValueKindForType(RhsT));

// Attempt the assignment in an unevaluated context within a SFINAE
// trap at translation unit scope.
EnterExpressionEvaluationContext Unevaluated(
Self, Sema::ExpressionEvaluationContext::Unevaluated);
Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
ExprResult Result = Self.BuildBinOp(/*S=*/nullptr, KeyLoc, BO_Assign, &Lhs,
&Rhs);
if (Result.isInvalid())
return false;

// Treat the assignment as unused for the purpose of -Wdeprecated-volatile.
Self.CheckUnusedVolatileAssignment(Result.get());

if (SFINAE.hasErrorOccurred())
return false;

// Under Objective-C ARC and Weak, if the destination has non-trivial
// Objective-C lifetime, this is a non-trivial assignment.
if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
return false;

QualType TheType = LhsT.getNonReferenceType();
if (!Self.Context.hasSameType(TheType, RhsT.getNonReferenceType()))
return false;
if (const auto *CE = dyn_cast<CXXOperatorCallExpr>(Result.get())) {
if (const FunctionDecl *Callee = CE->getDirectCallee()) {
return (Callee->isTrivial() && Self.Context.hasSameType(Callee->getParamDecl(0)->getType().getNonReferenceType(), TheType));
}
} else {
// It must be a primitive type, right?
return true;
}
return false;
}

static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
SourceLocation KWLoc,
ArrayRef<TypeSourceInfo *> Args,
Expand Down Expand Up @@ -5864,6 +5980,18 @@ static bool EvaluateBooleanTypeTrait(Sema &S, TypeTrait Kind,
if (RD && RD->isAbstract())
return false;

if (S.getLangOpts().P3279TriviallyFooable) {
if (Args.size() == 1) {
// Trivially Default Constructible: the status quo seems okay for this
} else if (Args.size() == 2) {
// Trivially Move/Copy Constructible
return IsP3279TriviallyConstructibleFrom(S, KWLoc, Args, RParenLoc);
} else {
S.Diag(KWLoc, diag::warn_deprecated_multi_argument_trivially_constructible);
return false;
}
}

llvm::BumpPtrAllocator OpaqueExprAllocator;
SmallVector<Expr *, 2> ArgExprs;
ArgExprs.reserve(Args.size() - 1);
Expand Down Expand Up @@ -6198,6 +6326,10 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceI
if (LhsT->isVoidType() || RhsT->isVoidType())
return false;

if (BTT == BTT_IsTriviallyAssignable && Self.getLangOpts().P3279TriviallyFooable) {
return IsP3279TriviallyAssignableFrom(Self, KeyLoc, LhsT, RhsT);
}

// Build expressions that emulate the effect of declval<T>() and
// declval<U>().
if (LhsT->isObjectType() || LhsT->isFunctionType())
Expand Down
77 changes: 77 additions & 0 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14356,6 +14356,50 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
// We matched an overloaded operator. Build a call to that
// operator.

if ((Opc == UO_PreDec || Opc == UO_PreInc || Opc == UO_PostDec || Opc == UO_PostInc) && !Args[0]->isLValue()) {
if (auto *MD = dyn_cast<CXXMethodDecl>(FnDecl)) {
if (MD->isImplicitObjectMemberFunction() && !MD->isConst() && (MD->getRefQualifier() == RQ_None)) {
// Do the overload resolution over again, as if this rvalue
// were a const-qualified xvalue. Would it still have worked?
QualType DifferentLhsT = Args[0]->getType().getNonReferenceType().withConst();
OpaqueValueExpr DifferentLhs(Args[0]->getExprLoc(), DifferentLhsT, VK_XValue);
Expr *DifferentArgs[2] = { &DifferentLhs, NumArgs == 2 ? Args[1] : nullptr };
ArrayRef<Expr *> DifferentArgsArray(DifferentArgs, NumArgs);

// Build the overload set.
OverloadCandidateSet DifferentCandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator);
AddNonMemberOperatorCandidates(Fns, DifferentArgsArray, DifferentCandidateSet);
AddMemberOperatorCandidates(Op, OpLoc, DifferentArgsArray, DifferentCandidateSet);
if (PerformADL) {
AddArgumentDependentLookupCandidates(OpName, OpLoc, DifferentArgsArray,
/*ExplicitTemplateArgs*/nullptr,
DifferentCandidateSet);
}
AddBuiltinOperatorCandidates(Op, OpLoc, DifferentArgsArray, DifferentCandidateSet);

OverloadCandidateSet::iterator DifferentBest;
OverloadingResult OR = DifferentCandidateSet.BestViableFunction(*this, OpLoc, DifferentBest);
if (OR != OR_Success) {
// If the operand had been a const xvalue, the operation would have
// been ill-formed. Therefore, this is probably a mistake by
// the user, and we should warn about it.
// However, `--end()` is pretty common in practice.
if (Opc == UO_PreInc || Opc == UO_PreDec) {
Diag(OpLoc, diag::warn_preincrement_of_class_rvalue)
<< (Opc == UO_PreInc)
<< Args[0]->getType() << Args[0]->getSourceRange();
Diag(FnDecl->getLocation(), diag::note_declared_at);
} else {
Diag(OpLoc, diag::warn_postincrement_of_class_rvalue)
<< (Opc == UO_PostInc)
<< Args[0]->getType() << Args[0]->getSourceRange();
Diag(FnDecl->getLocation(), diag::note_declared_at);
}
}
}
}
}

// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
CheckMemberOperatorAccess(OpLoc, Input, nullptr, Best->FoundDecl);
Expand Down Expand Up @@ -14644,6 +14688,39 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
OverloadedOperatorKind ChosenOp =
FnDecl->getDeclName().getCXXOverloadedOperator();

if ((isCompoundAssignmentOperator(ChosenOp) || ChosenOp == OO_Equal) && !Args[0]->isLValue()) {
if (auto *MD = dyn_cast<CXXMethodDecl>(FnDecl)) {
if (MD->isImplicitObjectMemberFunction() && !MD->isConst() && (MD->getRefQualifier() == RQ_None)) {
// Do the overload resolution over again, as if this rvalue
// were a const-qualified xvalue. Would it still have worked?
QualType DifferentLhsT = Args[0]->getType().getNonReferenceType().withConst();
OpaqueValueExpr DifferentLhs(Args[0]->getExprLoc(), DifferentLhsT, VK_XValue);
Expr *DifferentArgs[2] = { &DifferentLhs, Args[1] };

// Build the overload set.
OverloadCandidateSet DifferentCandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator,
OverloadCandidateSet::OperatorRewriteInfo(
Op, OpLoc, AllowRewrittenCandidates));
if (DefaultedFn)
DifferentCandidateSet.exclude(DefaultedFn);
LookupOverloadedBinOp(DifferentCandidateSet, Op, Fns, DifferentArgs, PerformADL);
OverloadCandidateSet::iterator DifferentBest;
OverloadingResult OR = DifferentCandidateSet.BestViableFunction(*this, OpLoc, DifferentBest);
if (OR != OR_Success) {
// If the LHS had been a const xvalue, the assignment would have
// been ill-formed. Therefore, this is probably a mistake by
// the user, and we should warn about it.
// But the operator= for tuple, pair, and reference gains `const` only in C++23,
// so emit a different warning, omitted from -Wall, for operator= prior to C++23.
Diag(OpLoc, (ChosenOp == OO_Equal && !getLangOpts().CPlusPlus23) ?
diag::warn_cxx23_compat_assign_to_class_rvalue : diag::warn_assign_to_class_rvalue)
<< Args[0]->getType() << Args[0]->getSourceRange();
Diag(FnDecl->getLocation(), diag::note_declared_at);
}
}
}
}

// C++2a [over.match.oper]p9:
// If a rewritten operator== candidate is selected by overload
// resolution for an operator@, its return type shall be cv bool
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Sema/SemaStmtAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,16 @@ static Attr *handleMustTailAttr(Sema &S, Stmt *St, const ParsedAttr &A,
return ::new (S.Context) MustTailAttr(S.Context, A);
}

static Attr *handleMustNrvoAttr(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) {
const ReturnStmt &RS = *cast<ReturnStmt>(St);
if (!RS.getNRVOCandidate()) {
S.Diag(St->getBeginLoc(), diag::err_mustnrvo_needs_variable) << A;
return nullptr;
}
return ::new (S.Context) MustNrvoAttr(S.Context, A);
}

static Attr *handleLikely(Sema &S, Stmt *St, const ParsedAttr &A,
SourceRange Range) {

Expand Down Expand Up @@ -665,6 +675,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
return handleNoInlineAttr(S, St, A, Range);
case ParsedAttr::AT_MustTail:
return handleMustTailAttr(S, St, A, Range);
case ParsedAttr::AT_MustNrvo:
return handleMustNrvoAttr(S, St, A, Range);
case ParsedAttr::AT_Likely:
return handleLikely(S, St, A, Range);
case ParsedAttr::AT_Unlikely:
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,28 @@ static void instantiateDependentAnnotationAttr(
}
}

static void instantiateDependentTriviallyRelocatableAttr(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const TriviallyRelocatableAttr *TRA, Decl *New) {
EnterExpressionEvaluationContext Unevaluated(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
Expr *Cond = TRA->getCond();
if (Cond != nullptr) {
ExprResult Result = S.SubstExpr(Cond, TemplateArgs);
if (Result.isInvalid())
return;
Cond = Result.getAs<Expr>();
assert(!Cond->isTypeDependent());
ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
if (Converted.isInvalid())
return;
Cond = Converted.get();
}

New->addAttr(::new (S.Context)
TriviallyRelocatableAttr(S.Context, *TRA, Cond));
}

static Expr *instantiateDependentFunctionAttrCondition(
Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs,
const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) {
Expand Down Expand Up @@ -782,6 +804,12 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
continue;
}

if (const auto *TRA = dyn_cast<TriviallyRelocatableAttr>(TmplAttr)) {
instantiateDependentTriviallyRelocatableAttr(*this, TemplateArgs, TRA,
New);
continue;
}

if (const auto *DiagnoseIf = dyn_cast<DiagnoseIfAttr>(TmplAttr)) {
instantiateDependentDiagnoseIfAttr(*this, TemplateArgs, DiagnoseIf, Tmpl,
cast<FunctionDecl>(New));
Expand Down
30 changes: 16 additions & 14 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2913,13 +2913,13 @@ void Sema::diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals,
}

// Diagnose pointless type qualifiers on the return type of a function.
static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
static void diagnoseRedundantReturnTypeQualifiers(unsigned DiagID, Sema &S, QualType RetTy,
Declarator &D,
unsigned FunctionChunkIndex) {
const DeclaratorChunk::FunctionTypeInfo &FTI =
D.getTypeObject(FunctionChunkIndex).Fun;
if (FTI.hasTrailingReturnType()) {
S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
S.diagnoseIgnoredQualifiers(DiagID,
RetTy.getLocalCVRQualifiers(),
FTI.getTrailingReturnTypeLoc());
return;
Expand All @@ -2936,7 +2936,7 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
case DeclaratorChunk::Pointer: {
DeclaratorChunk::PointerTypeInfo &PTI = OuterChunk.Ptr;
S.diagnoseIgnoredQualifiers(
diag::warn_qual_return_type,
DiagID,
PTI.TypeQuals,
SourceLocation(),
PTI.ConstQualLoc,
Expand All @@ -2956,7 +2956,7 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,
// FIXME: We can't currently provide an accurate source location and a
// fix-it hint for these.
unsigned AtomicQual = RetTy->isAtomicType() ? DeclSpec::TQ_atomic : 0;
S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
S.diagnoseIgnoredQualifiers(DiagID,
RetTy.getCVRQualifiers() | AtomicQual,
D.getIdentifierLoc());
return;
Expand All @@ -2973,7 +2973,7 @@ static void diagnoseRedundantReturnTypeQualifiers(Sema &S, QualType RetTy,

// Just parens all the way out to the decl specifiers. Diagnose any qualifiers
// which are present there.
S.diagnoseIgnoredQualifiers(diag::warn_qual_return_type,
S.diagnoseIgnoredQualifiers(DiagID,
D.getDeclSpec().getTypeQualifiers(),
D.getIdentifierLoc(),
D.getDeclSpec().getConstSpecLoc(),
Expand Down Expand Up @@ -5012,25 +5012,27 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,

// cv-qualifiers on return types are pointless except when the type is a
// class type in C++.
if ((T.getCVRQualifiers() || T->isAtomicType()) &&
!(S.getLangOpts().CPlusPlus &&
(T->isDependentType() || T->isRecordType()))) {
if (T->isVoidType() && !S.getLangOpts().CPlusPlus &&
if (T.getCVRQualifiers() || T->isAtomicType()) {
if (S.getLangOpts().CPlusPlus && (T->isDependentType() || T->isRecordType())) {
// Diagnose with a different diagnostic.
diagnoseRedundantReturnTypeQualifiers(diag::warn_qual_class_return_type, S, T, D, chunkIndex);
} else if (T->isVoidType() && !S.getLangOpts().CPlusPlus &&
D.getFunctionDefinitionKind() ==
FunctionDefinitionKind::Definition) {
// [6.9.1/3] qualified void return is invalid on a C
// function definition. Apparently ok on declarations and
// in C++ though (!)
S.Diag(DeclType.Loc, diag::err_func_returning_qualified_void) << T;
} else
diagnoseRedundantReturnTypeQualifiers(S, T, D, chunkIndex);
diagnoseRedundantReturnTypeQualifiers(diag::warn_qual_return_type, S, T, D, chunkIndex);

// C++2a [dcl.fct]p12:
// A volatile-qualified return type is deprecated
if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus20)
S.Diag(DeclType.Loc, diag::warn_deprecated_volatile_return) << T;
}

// C++2a [dcl.fct]p12:
// A volatile-qualified return type is deprecated
if (T.isVolatileQualified() && S.getLangOpts().CPlusPlus20)
S.Diag(DeclType.Loc, diag::warn_deprecated_volatile_return) << T;

// Objective-C ARC ownership qualifiers are ignored on the function
// return type (by type canonicalization). Complain if this attribute
// was written here.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/RegionStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class BindingKey {
/// Create a key for a binding to region \p r, which has a symbolic offset
/// from region \p Base.
explicit BindingKey(const SubRegion *r, const SubRegion *Base, Kind k)
: P(r, k | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) {
: P(r, unsigned(k) | Symbolic), Data(reinterpret_cast<uintptr_t>(Base)) {
assert(r && Base && "Must have known regions.");
assert(getConcreteOffsetRegion() == Base && "Failed to store base region");
}
Expand Down
1 change: 1 addition & 0 deletions clang/test/AST/ast-dump-decl-context-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ void S::Method() {}
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down
22 changes: 11 additions & 11 deletions clang/test/AST/ast-dump-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ namespace testTypeAliasTemplateDecl {
namespace testCXXRecordDecl {
class TestEmpty {};
// CHECK: CXXRecordDecl{{.*}} class TestEmpty
// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: DefaultConstructor exists trivial constexpr
// CHECK-NEXT: CopyConstructor simple trivial has_const_param
// CHECK-NEXT: MoveConstructor exists simple trivial
Expand Down Expand Up @@ -319,7 +319,7 @@ namespace testClassTemplateDecl {
// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-40]]:3, line:[[@LINE-34]]:3> line:[[@LINE-40]]:30 TestClassTemplate{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:24, line:[[@LINE-36]]:3> line:[[@LINE-42]]:30 class TestClassTemplate definition{{$}}
// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefinitionData standard_layout trivially_relocatable has_user_declared_ctor can_const_default_init{{$}}
// CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided{{$}}
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | | |-MoveConstructor{{$}}
Expand Down Expand Up @@ -356,7 +356,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate'{{$}}

// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-67]]:3, line:[[@LINE-65]]:3> line:[[@LINE-67]]:20 class TestClassTemplate definition explicit_specialization{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivial literal{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivially_relocatable trivial literal{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand Down Expand Up @@ -409,7 +409,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:25, col:34> col:34 typename depth 0 index 1 T2{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <col:38, line:[[@LINE-107]]:3> line:[[@LINE-109]]:44 class TestClassTemplatePartial definition{{$}}
// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal{{$}}
// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivially_relocatable trivial literal{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand All @@ -420,7 +420,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-117]]:5, col:9> col:9 i 'int'{{$}}

// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-117]]:3, line:[[@LINE-115]]:3> line:[[@LINE-117]]:31 class TestClassTemplatePartial definition explicit_specialization{{$}}
// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal{{$}}
// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivially_relocatable trivial literal{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand Down Expand Up @@ -448,7 +448,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | |-inherited from TemplateTypeParm 0x{{.+}} 'T'{{$}}
// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int'{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:24, col:57> col:31 struct TestTemplateDefaultType definition{{$}}
// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand Down Expand Up @@ -477,7 +477,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | |-inherited from TemplateTemplateParm 0x{{.+}} 'TT'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:3, line:{{.+}}:3> line:{{.+}}:30 TestClassTemplate
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:{{.*}}:41, col:82> col:48 struct TestTemplateTemplateDefaultType definition{{$}}
// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand Down Expand Up @@ -518,7 +518,7 @@ namespace testCanonicalTemplate {
// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-4]]:3, line:[[@LINE-2]]:3> line:[[@LINE-4]]:31 TestClassTemplate{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, line:[[@LINE-4]]:3> line:[[@LINE-6]]:31 class TestClassTemplate definition{{$}}
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr{{$}}
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand All @@ -531,7 +531,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:14, col:23> col:23 typename depth 1 index 0 T2{{$}}
// CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} <col:34, col:40> col:40 class TestClassTemplate{{$}}
// CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-19]]:3, line:[[@LINE-17]]:3> line:[[@LINE-19]]:31 class TestClassTemplate definition implicit_instantiation{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial{{$}}
Expand Down Expand Up @@ -564,7 +564,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 class TestClassTemplate2{{$}}
// CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-6]]:3, line:[[@LINE-5]]:3> line:[[@LINE-6]]:31 class TestClassTemplate2 definition implicit_instantiation{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr{{$}}
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param{{$}}
// CHECK-NEXT: | |-MoveConstructor exists simple trivial{{$}}
Expand All @@ -590,7 +590,7 @@ namespace testCanonicalTemplate {
// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-30]]:3, line:[[@LINE-29]]:3> line:[[@LINE-30]]:31 TestClassTemplate2{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 typename depth 0 index 0 T1{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <col:25, line:[[@LINE-31]]:3> line:[[@LINE-32]]:31 class TestClassTemplate2 definition{{$}}
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr{{$}}
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param{{$}}
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit{{$}}
Expand Down
2 changes: 2 additions & 0 deletions clang/test/AST/ast-dump-default-init-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ void test() {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -383,6 +384,7 @@ void test() {
// CHECK-NEXT: "isAggregate": true,
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down
16 changes: 16 additions & 0 deletions clang/test/AST/ast-dump-expr-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3760,6 +3760,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -3934,6 +3935,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLambda": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -4145,6 +4147,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLambda": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -4462,6 +4465,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -4664,6 +4668,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -4916,6 +4921,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLambda": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -5137,6 +5143,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -5283,6 +5290,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -5525,6 +5533,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -5671,6 +5680,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -5909,6 +5919,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLambda": true,
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -6470,6 +6481,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLambda": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -6737,6 +6749,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -6941,6 +6954,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -7143,6 +7157,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -7345,6 +7360,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down
1 change: 1 addition & 0 deletions clang/test/AST/ast-dump-funcs-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,7 @@ struct TestFriends {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down
34 changes: 17 additions & 17 deletions clang/test/AST/ast-dump-lambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: `-CompoundStmt {{.*}} <col:46, line:37:1>
// CHECK-NEXT: |-DeclStmt {{.*}} <line:16:3, line:21:4>
// CHECK-NEXT: | `-CXXRecordDecl {{.*}} <line:16:3, line:21:3> line:16:10{{( imported)?}}{{( <undeserialized declarations>)?}} struct V definition
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -55,7 +55,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:14, line:20:5>
// CHECK-NEXT: | |-LambdaExpr {{.*}} <line:18:7, col:15> '(lambda at {{.*}}ast-dump-lambda.cpp:18:7)'
// CHECK-NEXT: | | |-CXXRecordDecl {{.*}} <col:7> col:7{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | | |-DefinitionData lambda standard_layout trivially_copyable can_const_default_init
// CHECK-NEXT: | | | |-DefinitionData lambda standard_layout trivially_copyable trivially_relocatable can_const_default_init
// CHECK-NEXT: | | | | |-DefaultConstructor
// CHECK-NEXT: | | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -70,7 +70,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | | `-CompoundStmt {{.*}} <col:14, col:15>
// CHECK-NEXT: | `-LambdaExpr {{.*}} <line:19:7, col:16> '(lambda at {{.*}}ast-dump-lambda.cpp:19:7)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:7> col:7{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable trivially_relocatable can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -89,7 +89,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-VarDecl {{.*}} <col:3, col:10> col:10{{( imported)?}} referenced c 'int'
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:23:3, col:9> '(lambda at {{.*}}ast-dump-lambda.cpp:23:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -103,7 +103,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:8, col:9>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:24:3, col:19> '(lambda at {{.*}}ast-dump-lambda.cpp:24:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -119,7 +119,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, col:19>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:25:3, col:11> '(lambda at {{.*}}ast-dump-lambda.cpp:25:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable trivially_relocatable can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -134,7 +134,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:10, col:11>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:26:3, col:8> '(lambda at {{.*}}ast-dump-lambda.cpp:26:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -146,7 +146,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:7, col:8>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:27:3, col:19> '(lambda at {{.*}}ast-dump-lambda.cpp:27:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -162,7 +162,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:16> 'const int' lvalue Var {{.*}} 'b' 'int' refers_to_enclosing_variable_or_capture
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:28:3, col:8> '(lambda at {{.*}}ast-dump-lambda.cpp:28:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -174,7 +174,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:7, col:8>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:29:3, col:19> '(lambda at {{.*}}ast-dump-lambda.cpp:29:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -190,7 +190,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:16> 'int' lvalue Var {{.*}} 'c' 'int' refers_to_enclosing_variable_or_capture
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:30:3, col:27> '(lambda at {{.*}}ast-dump-lambda.cpp:30:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand Down Expand Up @@ -219,7 +219,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-DeclRefExpr {{.*}} <col:24> 'int' lvalue Var {{.*}} 'c' 'int' refers_to_enclosing_variable_or_capture
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:31:3, col:19> '(lambda at {{.*}}ast-dump-lambda.cpp:31:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda standard_layout trivially_copyable trivially_relocatable can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -236,7 +236,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, col:19>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:32:3, col:19> '(lambda at {{.*}}ast-dump-lambda.cpp:32:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -250,7 +250,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:18, col:19>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:33:3, col:17> '(lambda at {{.*}}ast-dump-lambda.cpp:33:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -264,7 +264,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:16, col:17>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:34:3, col:18> '(lambda at {{.*}}ast-dump-lambda.cpp:34:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -278,7 +278,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-CompoundStmt {{.*}} <col:17, col:18>
// CHECK-NEXT: |-LambdaExpr {{.*}} <line:35:3, col:27> '(lambda at {{.*}}ast-dump-lambda.cpp:35:3)'
// CHECK-NEXT: | |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -296,7 +296,7 @@ template <typename... Ts> void test(Ts... a) {
// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:24> 'int' 0
// CHECK-NEXT: `-LambdaExpr {{.*}} <line:36:3, col:23> '(lambda at {{.*}}ast-dump-lambda.cpp:36:3)'
// CHECK-NEXT: |-CXXRecordDecl {{.*}} <col:3> col:3{{( imported)?}} implicit{{( <undeserialized declarations>)?}} class definition
// CHECK-NEXT: | |-DefinitionData lambda empty standard_layout trivially_copyable literal can_const_default_init
// CHECK-NEXT: | |-DefinitionData lambda empty standard_layout trivially_copyable trivially_relocatable literal can_const_default_init
// CHECK-NEXT: | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ int test(float &&f, short &&s) {
// CHECK: |-ClassTemplateDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, col:66> col:29 remove_reference
// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_1:0x[a-z0-9]*]] <col:11, col:17> col:17 referenced class depth 0 index 0 _Tp
// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_2:0x[a-z0-9]*]] <col:22, col:66> col:29 struct remove_reference definition
// CHECK-NEXT: | | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -110,7 +110,7 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | | `-TemplateTypeParmType [[ADDR_5:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0
// CHECK-NEXT: | | `-TemplateTypeParm [[ADDR_1]] '_Tp'
// CHECK-NEXT: | |-ClassTemplateSpecializationDecl [[ADDR_6:0x[a-z0-9]*]] <line:6:1, col:73> col:29 struct remove_reference definition
// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -126,7 +126,7 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference'
// CHECK-NEXT: | | `-BuiltinType [[ADDR_8]] 'float'
// CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_14:0x[a-z0-9]*]] <col:1, col:73> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -142,7 +142,7 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference'
// CHECK-NEXT: | `-BuiltinType [[ADDR_16]] 'short'
// CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_20:0x[a-z0-9]*]] <col:1, col:73> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -158,7 +158,7 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | `-TemplateTypeParmType [[ADDR_12:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm [[ADDR_13]] '_Tp'
// CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_25:0x[a-z0-9]*]] <line:7:1, col:74> col:29 struct remove_reference definition
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
// CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
// CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ int test() {
// CHECK: |-ClassTemplateDecl [[ADDR_0:0x[a-z0-9]*]] <{{.*}}, line:7:1> line:5:30 S
// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_1:0x[a-z0-9]*]] <col:11, col:20> col:20 referenced typename depth 0 index 0 T
// CHECK-NEXT: | |-CXXRecordDecl [[ADDR_2:0x[a-z0-9]*]] <col:23, line:7:1> line:5:30 struct S definition
// CHECK-NEXT: | | |-DefinitionData empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
// CHECK-NEXT: | | |-DefinitionData empty standard_layout trivially_copyable trivially_relocatable has_user_declared_ctor can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial needs_implicit
Expand All @@ -60,7 +60,7 @@ int test() {
// CHECK-NEXT: | | |-ParmVarDecl [[ADDR_6:0x[a-z0-9]*]] <col:10, col:12> col:13 'T *'
// CHECK-NEXT: | | `-CompoundStmt [[ADDR_7:0x[a-z0-9]*]] <col:15, col:16>
// CHECK-NEXT: | |-ClassTemplateSpecializationDecl [[ADDR_8:0x[a-z0-9]*]] <line:5:1, line:7:1> line:5:30 struct S definition
// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable has_user_declared_ctor can_const_default_init
// CHECK-NEXT: | | |-DefinitionData pass_in_registers empty standard_layout trivially_copyable trivially_relocatable has_user_declared_ctor can_const_default_init
// CHECK-NEXT: | | | |-DefaultConstructor defaulted_is_constexpr
// CHECK-NEXT: | | | |-CopyConstructor simple trivial has_const_param implicit_has_const_param
// CHECK-NEXT: | | | |-MoveConstructor exists simple trivial
Expand Down
27 changes: 27 additions & 0 deletions clang/test/AST/ast-dump-record-definition-data-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -386,6 +387,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {
// CHECK-NEXT: "exists": true,
Expand Down Expand Up @@ -774,6 +776,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {}
// CHECK-NEXT: },
Expand Down Expand Up @@ -916,6 +919,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {}
// CHECK-NEXT: },
Expand Down Expand Up @@ -1065,6 +1069,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1164,6 +1169,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1289,6 +1295,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1412,6 +1419,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1565,6 +1573,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1961,6 +1970,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2213,6 +2223,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2335,6 +2346,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2463,6 +2475,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2592,6 +2605,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isEmpty": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -3007,6 +3021,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -3668,6 +3683,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {},
// CHECK-NEXT: "moveCtor": {}
// CHECK-NEXT: },
Expand Down Expand Up @@ -3919,6 +3935,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isEmpty": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4069,6 +4086,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4171,6 +4189,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4317,6 +4336,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isEmpty": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4464,6 +4484,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4590,6 +4611,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4716,6 +4738,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4813,6 +4836,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4970,6 +4994,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -5071,6 +5096,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isLiteral": true,
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -5220,6 +5246,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down
11 changes: 11 additions & 0 deletions clang/test/AST/ast-dump-record-definition-data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,17 @@ struct IsNotTriviallyCopyable {
IsNotTriviallyCopyable(const IsNotTriviallyCopyable&) {}
};

struct IsTriviallyRelocatable {
// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+2]]:1> line:[[@LINE-1]]:8 struct IsTriviallyRelocatable definition
// CHECK-NEXT: DefinitionData {{.*}}trivially_relocatable{{.*}}
};

struct IsNotTriviallyRelocatable {
// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsNotTriviallyRelocatable definition
// CHECK-NOT: DefinitionData {{.*}}trivially_relocatable{{.*}}
IsNotTriviallyRelocatable(const IsNotTriviallyRelocatable&) {}
};

struct IsPOD {
// CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+3]]:1> line:[[@LINE-1]]:8 struct IsPOD definition
// CHECK-NEXT: DefinitionData {{.*}}pod{{.*}}
Expand Down
17 changes: 17 additions & 0 deletions clang/test/AST/ast-dump-records-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -626,6 +627,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -722,6 +724,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -851,6 +854,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1050,6 +1054,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1250,6 +1255,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1477,6 +1483,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1898,6 +1905,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -1994,6 +2002,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2123,6 +2132,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2322,6 +2332,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -2525,6 +2536,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "simple": true,
Expand Down Expand Up @@ -2766,6 +2778,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "simple": true,
Expand Down Expand Up @@ -3007,6 +3020,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "simple": true,
Expand Down Expand Up @@ -3249,6 +3263,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -3360,6 +3375,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down Expand Up @@ -4202,6 +4218,7 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: "isStandardLayout": true,
// CHECK-NEXT: "isTrivial": true,
// CHECK-NEXT: "isTriviallyCopyable": true,
// CHECK-NEXT: "isTriviallyRelocatable": true,
// CHECK-NEXT: "moveAssign": {
// CHECK-NEXT: "exists": true,
// CHECK-NEXT: "needsImplicit": true,
Expand Down
Loading