Revert "[Sema] Diagnose default-initialization, destruction, and copying of"
This reverts commit r365985.
Prior to r365985, clang used to mark C union fields that have
non-trivial ObjC ownership qualifiers as unavailable if the union was
declared in a system header. r365985 stopped doing so, which caused the
swift compiler to crash when it tried to import a non-trivial union.
I have a patch that fixes the crash (https://reviews.llvm.org/D65256),
but I'm temporarily reverting the original patch until we can decide on
whether it's taking the right approach.
llvm-svn: 367076
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 21cf9da..21dd542 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -4252,9 +4252,6 @@
setNonTrivialToPrimitiveDefaultInitialize(false);
setNonTrivialToPrimitiveCopy(false);
setNonTrivialToPrimitiveDestroy(false);
- setHasNonTrivialToPrimitiveDefaultInitializeCUnion(false);
- setHasNonTrivialToPrimitiveDestructCUnion(false);
- setHasNonTrivialToPrimitiveCopyCUnion(false);
setParamDestroyedInCallee(false);
setArgPassingRestrictions(APK_CanPassInRegs);
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index ed75a0b..8d474a8 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2276,16 +2276,60 @@
getObjCLifetime() != Qualifiers::OCL_Weak;
}
-bool QualType::hasNonTrivialToPrimitiveDefaultInitializeCUnion(const RecordDecl *RD) {
- return RD->hasNonTrivialToPrimitiveDefaultInitializeCUnion();
-}
+namespace {
+// Helper class that determines whether this is a type that is non-trivial to
+// primitive copy or move, or is a struct type that has a field of such type.
+template <bool IsMove>
+struct IsNonTrivialCopyMoveVisitor
+ : CopiedTypeVisitor<IsNonTrivialCopyMoveVisitor<IsMove>, IsMove, bool> {
+ using Super =
+ CopiedTypeVisitor<IsNonTrivialCopyMoveVisitor<IsMove>, IsMove, bool>;
+ IsNonTrivialCopyMoveVisitor(const ASTContext &C) : Ctx(C) {}
+ void preVisit(QualType::PrimitiveCopyKind PCK, QualType QT) {}
-bool QualType::hasNonTrivialToPrimitiveDestructCUnion(const RecordDecl *RD) {
- return RD->hasNonTrivialToPrimitiveDestructCUnion();
-}
+ bool visitWithKind(QualType::PrimitiveCopyKind PCK, QualType QT) {
+ if (const auto *AT = this->Ctx.getAsArrayType(QT))
+ return this->asDerived().visit(Ctx.getBaseElementType(AT));
+ return Super::visitWithKind(PCK, QT);
+ }
-bool QualType::hasNonTrivialToPrimitiveCopyCUnion(const RecordDecl *RD) {
- return RD->hasNonTrivialToPrimitiveCopyCUnion();
+ bool visitARCStrong(QualType QT) { return true; }
+ bool visitARCWeak(QualType QT) { return true; }
+ bool visitTrivial(QualType QT) { return false; }
+ // Volatile fields are considered trivial.
+ bool visitVolatileTrivial(QualType QT) { return false; }
+
+ bool visitStruct(QualType QT) {
+ const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ // We don't want to apply the C restriction in C++ because C++
+ // (1) can apply the restriction at a finer grain by banning copying or
+ // destroying the union, and
+ // (2) allows users to override these restrictions by declaring explicit
+ // constructors/etc, which we're not proposing to add to C.
+ if (isa<CXXRecordDecl>(RD))
+ return false;
+ for (const FieldDecl *FD : RD->fields())
+ if (this->asDerived().visit(FD->getType()))
+ return true;
+ return false;
+ }
+
+ const ASTContext &Ctx;
+};
+
+} // namespace
+
+bool QualType::isNonTrivialPrimitiveCType(const ASTContext &Ctx) const {
+ if (isNonTrivialToPrimitiveDefaultInitialize())
+ return true;
+ DestructionKind DK = isDestructedType();
+ if (DK != DK_none && DK != DK_cxx_destructor)
+ return true;
+ if (IsNonTrivialCopyMoveVisitor<false>(Ctx).visit(*this))
+ return true;
+ if (IsNonTrivialCopyMoveVisitor<true>(Ctx).visit(*this))
+ return true;
+ return false;
}
QualType::PrimitiveDefaultInitializeKind
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 11fed28..3941643 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1658,24 +1658,12 @@
// Set the EscapingByref flag of __block variables captured by
// escaping blocks.
for (const BlockDecl *BD : FSI.Blocks) {
+ if (BD->doesNotEscape())
+ continue;
for (const BlockDecl::Capture &BC : BD->captures()) {
VarDecl *VD = BC.getVariable();
- if (VD->hasAttr<BlocksAttr>()) {
- // Nothing to do if this is a __block variable captured by a
- // non-escaping block.
- if (BD->doesNotEscape())
- continue;
+ if (VD->hasAttr<BlocksAttr>())
VD->setEscapingByref();
- }
- // Check whether the captured variable is or contains an object of
- // non-trivial C union type.
- QualType CapType = BC.getVariable()->getType();
- if (CapType.hasNonTrivialToPrimitiveDestructCUnion() ||
- CapType.hasNonTrivialToPrimitiveCopyCUnion())
- S.checkNonTrivialCUnion(BC.getVariable()->getType(),
- BD->getCaretLocation(),
- Sema::NTCUC_BlockCapture,
- Sema::NTCUK_Destruct|Sema::NTCUK_Copy);
}
}
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2602e52..1c7b2b0 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -22,7 +22,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/EvaluatedExprVisitor.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/NonTrivialTypeVisitor.h"
#include "clang/AST/StmtCXX.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -6505,11 +6504,6 @@
if (D.isInvalidType())
NewVD->setInvalidDecl();
-
- if (NewVD->getType().hasNonTrivialToPrimitiveDestructCUnion() &&
- NewVD->hasLocalStorage())
- checkNonTrivialCUnion(NewVD->getType(), NewVD->getLocation(),
- NTCUC_AutoVar, NTCUK_Destruct);
} else {
bool Invalid = false;
@@ -8932,12 +8926,6 @@
<< FunctionType::getNameForCallConv(CC);
}
}
-
- if (NewFD->getReturnType().hasNonTrivialToPrimitiveDestructCUnion() ||
- NewFD->getReturnType().hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(NewFD->getReturnType(),
- NewFD->getReturnTypeSourceRange().getBegin(),
- NTCUC_FunctionReturn, NTCUK_Destruct|NTCUK_Copy);
} else {
// C++11 [replacement.functions]p3:
// The program's definitions shall not be specified as inline.
@@ -11084,264 +11072,6 @@
return VDecl->isInvalidDecl();
}
-void Sema::checkNonTrivialCUnionInInitializer(const Expr *Init,
- SourceLocation Loc) {
- if (auto *CE = dyn_cast<ConstantExpr>(Init))
- Init = CE->getSubExpr();
-
- QualType InitType = Init->getType();
- assert((InitType.hasNonTrivialToPrimitiveDefaultInitializeCUnion() ||
- InitType.hasNonTrivialToPrimitiveCopyCUnion()) &&
- "shouldn't be called if type doesn't have a non-trivial C struct");
- if (auto *ILE = dyn_cast<InitListExpr>(Init)) {
- for (auto I : ILE->inits()) {
- if (!I->getType().hasNonTrivialToPrimitiveDefaultInitializeCUnion() &&
- !I->getType().hasNonTrivialToPrimitiveCopyCUnion())
- continue;
- SourceLocation SL = I->getExprLoc();
- checkNonTrivialCUnionInInitializer(I, SL.isValid() ? SL : Loc);
- }
- return;
- }
-
- if (isa<ImplicitValueInitExpr>(Init)) {
- if (InitType.hasNonTrivialToPrimitiveDefaultInitializeCUnion())
- checkNonTrivialCUnion(InitType, Loc, NTCUC_DefaultInitializedObject,
- NTCUK_Init);
- } else {
- // Assume all other explicit initializers involving copying some existing
- // object.
- // TODO: ignore any explicit initializers where we can guarantee
- // copy-elision.
- if (InitType.hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(InitType, Loc, NTCUC_CopyInit, NTCUK_Copy);
- }
-}
-
-namespace {
-
-struct DiagNonTrivalCUnionDefaultInitializeVisitor
- : DefaultInitializedTypeVisitor<DiagNonTrivalCUnionDefaultInitializeVisitor,
- void> {
- using Super =
- DefaultInitializedTypeVisitor<DiagNonTrivalCUnionDefaultInitializeVisitor,
- void>;
-
- DiagNonTrivalCUnionDefaultInitializeVisitor(
- QualType OrigTy, SourceLocation OrigLoc,
- Sema::NonTrivialCUnionContext UseContext, Sema &S)
- : OrigTy(OrigTy), OrigLoc(OrigLoc), UseContext(UseContext), S(S) {}
-
- void visitWithKind(QualType::PrimitiveDefaultInitializeKind PDIK, QualType QT,
- const FieldDecl *FD, bool InNonTrivialUnion) {
- if (const auto *AT = S.Context.getAsArrayType(QT))
- return this->asDerived().visit(S.Context.getBaseElementType(AT), FD,
- InNonTrivialUnion);
- return Super::visitWithKind(PDIK, QT, FD, InNonTrivialUnion);
- }
-
- void visitARCStrong(QualType QT, const FieldDecl *FD,
- bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 0 << QT << FD->getName();
- }
-
- void visitARCWeak(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 0 << QT << FD->getName();
- }
-
- void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
- if (RD->isUnion()) {
- if (OrigLoc.isValid()) {
- bool IsUnion = false;
- if (auto *OrigRD = OrigTy->getAsRecordDecl())
- IsUnion = OrigRD->isUnion();
- S.Diag(OrigLoc, diag::err_non_trivial_c_union_in_invalid_context)
- << 0 << OrigTy << IsUnion << UseContext;
- // Reset OrigLoc so that this diagnostic is emitted only once.
- OrigLoc = SourceLocation();
- }
- InNonTrivialUnion = true;
- }
-
- if (InNonTrivialUnion)
- S.Diag(RD->getLocation(), diag::note_non_trivial_c_union)
- << 0 << 0 << QT.getUnqualifiedType() << "";
-
- for (const FieldDecl *FD : RD->fields())
- asDerived().visit(FD->getType(), FD, InNonTrivialUnion);
- }
-
- void visitTrivial(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {}
-
- // The non-trivial C union type or the struct/union type that contains a
- // non-trivial C union.
- QualType OrigTy;
- SourceLocation OrigLoc;
- Sema::NonTrivialCUnionContext UseContext;
- Sema &S;
-};
-
-struct DiagNonTrivalCUnionDestructedTypeVisitor
- : DestructedTypeVisitor<DiagNonTrivalCUnionDestructedTypeVisitor, void> {
- using Super =
- DestructedTypeVisitor<DiagNonTrivalCUnionDestructedTypeVisitor, void>;
-
- DiagNonTrivalCUnionDestructedTypeVisitor(
- QualType OrigTy, SourceLocation OrigLoc,
- Sema::NonTrivialCUnionContext UseContext, Sema &S)
- : OrigTy(OrigTy), OrigLoc(OrigLoc), UseContext(UseContext), S(S) {}
-
- void visitWithKind(QualType::DestructionKind DK, QualType QT,
- const FieldDecl *FD, bool InNonTrivialUnion) {
- if (const auto *AT = S.Context.getAsArrayType(QT))
- return this->asDerived().visit(S.Context.getBaseElementType(AT), FD,
- InNonTrivialUnion);
- return Super::visitWithKind(DK, QT, FD, InNonTrivialUnion);
- }
-
- void visitARCStrong(QualType QT, const FieldDecl *FD,
- bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 1 << QT << FD->getName();
- }
-
- void visitARCWeak(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 1 << QT << FD->getName();
- }
-
- void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
- if (RD->isUnion()) {
- if (OrigLoc.isValid()) {
- bool IsUnion = false;
- if (auto *OrigRD = OrigTy->getAsRecordDecl())
- IsUnion = OrigRD->isUnion();
- S.Diag(OrigLoc, diag::err_non_trivial_c_union_in_invalid_context)
- << 1 << OrigTy << IsUnion << UseContext;
- // Reset OrigLoc so that this diagnostic is emitted only once.
- OrigLoc = SourceLocation();
- }
- InNonTrivialUnion = true;
- }
-
- if (InNonTrivialUnion)
- S.Diag(RD->getLocation(), diag::note_non_trivial_c_union)
- << 0 << 1 << QT.getUnqualifiedType() << "";
-
- for (const FieldDecl *FD : RD->fields())
- asDerived().visit(FD->getType(), FD, InNonTrivialUnion);
- }
-
- void visitTrivial(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {}
- void visitCXXDestructor(QualType QT, const FieldDecl *FD,
- bool InNonTrivialUnion) {}
-
- // The non-trivial C union type or the struct/union type that contains a
- // non-trivial C union.
- QualType OrigTy;
- SourceLocation OrigLoc;
- Sema::NonTrivialCUnionContext UseContext;
- Sema &S;
-};
-
-struct DiagNonTrivalCUnionCopyVisitor
- : CopiedTypeVisitor<DiagNonTrivalCUnionCopyVisitor, false, void> {
- using Super = CopiedTypeVisitor<DiagNonTrivalCUnionCopyVisitor, false, void>;
-
- DiagNonTrivalCUnionCopyVisitor(QualType OrigTy, SourceLocation OrigLoc,
- Sema::NonTrivialCUnionContext UseContext,
- Sema &S)
- : OrigTy(OrigTy), OrigLoc(OrigLoc), UseContext(UseContext), S(S) {}
-
- void visitWithKind(QualType::PrimitiveCopyKind PCK, QualType QT,
- const FieldDecl *FD, bool InNonTrivialUnion) {
- if (const auto *AT = S.Context.getAsArrayType(QT))
- return this->asDerived().visit(S.Context.getBaseElementType(AT), FD,
- InNonTrivialUnion);
- return Super::visitWithKind(PCK, QT, FD, InNonTrivialUnion);
- }
-
- void visitARCStrong(QualType QT, const FieldDecl *FD,
- bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 2 << QT << FD->getName();
- }
-
- void visitARCWeak(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- if (InNonTrivialUnion)
- S.Diag(FD->getLocation(), diag::note_non_trivial_c_union)
- << 1 << 2 << QT << FD->getName();
- }
-
- void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
- if (RD->isUnion()) {
- if (OrigLoc.isValid()) {
- bool IsUnion = false;
- if (auto *OrigRD = OrigTy->getAsRecordDecl())
- IsUnion = OrigRD->isUnion();
- S.Diag(OrigLoc, diag::err_non_trivial_c_union_in_invalid_context)
- << 2 << OrigTy << IsUnion << UseContext;
- // Reset OrigLoc so that this diagnostic is emitted only once.
- OrigLoc = SourceLocation();
- }
- InNonTrivialUnion = true;
- }
-
- if (InNonTrivialUnion)
- S.Diag(RD->getLocation(), diag::note_non_trivial_c_union)
- << 0 << 2 << QT.getUnqualifiedType() << "";
-
- for (const FieldDecl *FD : RD->fields())
- asDerived().visit(FD->getType(), FD, InNonTrivialUnion);
- }
-
- void preVisit(QualType::PrimitiveCopyKind PCK, QualType QT,
- const FieldDecl *FD, bool InNonTrivialUnion) {}
- void visitTrivial(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {}
- void visitVolatileTrivial(QualType QT, const FieldDecl *FD,
- bool InNonTrivialUnion) {}
-
- // The non-trivial C union type or the struct/union type that contains a
- // non-trivial C union.
- QualType OrigTy;
- SourceLocation OrigLoc;
- Sema::NonTrivialCUnionContext UseContext;
- Sema &S;
-};
-
-} // namespace
-
-void Sema::checkNonTrivialCUnion(QualType QT, SourceLocation Loc,
- NonTrivialCUnionContext UseContext,
- unsigned NonTrivialKind) {
- assert((QT.hasNonTrivialToPrimitiveDefaultInitializeCUnion() ||
- QT.hasNonTrivialToPrimitiveDestructCUnion() ||
- QT.hasNonTrivialToPrimitiveCopyCUnion()) &&
- "shouldn't be called if type doesn't have a non-trivial C union");
-
- if ((NonTrivialKind & NTCUK_Init) &&
- QT.hasNonTrivialToPrimitiveDefaultInitializeCUnion())
- DiagNonTrivalCUnionDefaultInitializeVisitor(QT, Loc, UseContext, *this)
- .visit(QT, nullptr, false);
- if ((NonTrivialKind & NTCUK_Destruct) &&
- QT.hasNonTrivialToPrimitiveDestructCUnion())
- DiagNonTrivalCUnionDestructedTypeVisitor(QT, Loc, UseContext, *this)
- .visit(QT, nullptr, false);
- if ((NonTrivialKind & NTCUK_Copy) && QT.hasNonTrivialToPrimitiveCopyCUnion())
- DiagNonTrivalCUnionCopyVisitor(QT, Loc, UseContext, *this)
- .visit(QT, nullptr, false);
-}
-
/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
@@ -11747,12 +11477,6 @@
CheckForConstantInitializer(Init, DclT);
}
- QualType InitType = Init->getType();
- if (!InitType.isNull() &&
- (InitType.hasNonTrivialToPrimitiveDefaultInitializeCUnion() ||
- InitType.hasNonTrivialToPrimitiveCopyCUnion()))
- checkNonTrivialCUnionInInitializer(Init, Init->getExprLoc());
-
// We will represent direct-initialization similarly to copy-initialization:
// int x(1); -as-> int x = 1;
// ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c);
@@ -11877,14 +11601,7 @@
return;
}
- VarDecl::DefinitionKind DefKind = Var->isThisDeclarationADefinition();
- if (!Var->isInvalidDecl() && DefKind != VarDecl::DeclarationOnly &&
- Var->getType().hasNonTrivialToPrimitiveDefaultInitializeCUnion())
- checkNonTrivialCUnion(Var->getType(), Var->getLocation(),
- NTCUC_DefaultInitializedObject, NTCUK_Init);
-
-
- switch (DefKind) {
+ switch (Var->isThisDeclarationADefinition()) {
case VarDecl::Definition:
if (!Var->isStaticDataMember() || !Var->getAnyInitializer())
break;
@@ -12977,11 +12694,6 @@
Context.getAdjustedParameterType(T),
TSInfo, SC, nullptr);
- if (New->getType().hasNonTrivialToPrimitiveDestructCUnion() ||
- New->getType().hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(New->getType(), New->getLocation(),
- NTCUC_FunctionParam, NTCUK_Destruct|NTCUK_Copy);
-
// Parameters can not be abstract class types.
// For record types, this is done by the AbstractClassUsageDiagnoser once
// the class has been completely parsed.
@@ -16228,6 +15940,7 @@
// Verify that all the fields are okay.
SmallVector<FieldDecl*, 32> RecFields;
+ bool ObjCFieldLifetimeErrReported = false;
for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end();
i != end; ++i) {
FieldDecl *FD = cast<FieldDecl>(*i);
@@ -16366,12 +16079,38 @@
Record->setHasObjectMember(true);
if (Record && FDTTy->getDecl()->hasVolatileMember())
Record->setHasVolatileMember(true);
+ if (Record && Record->isUnion() &&
+ FD->getType().isNonTrivialPrimitiveCType(Context))
+ Diag(FD->getLocation(),
+ diag::err_nontrivial_primitive_type_in_union);
} else if (FDTy->isObjCObjectType()) {
/// A field cannot be an Objective-c object
Diag(FD->getLocation(), diag::err_statically_allocated_object)
<< FixItHint::CreateInsertion(FD->getLocation(), "*");
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
+ } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+ Record && !ObjCFieldLifetimeErrReported && Record->isUnion() &&
+ !getLangOpts().CPlusPlus) {
+ // It's an error in ARC or Weak if a field has lifetime.
+ // We don't want to report this in a system header, though,
+ // so we just make the field unavailable.
+ // FIXME: that's really not sufficient; we need to make the type
+ // itself invalid to, say, initialize or copy.
+ QualType T = FD->getType();
+ if (T.hasNonTrivialObjCLifetime()) {
+ SourceLocation loc = FD->getLocation();
+ if (getSourceManager().isInSystemHeader(loc)) {
+ if (!FD->hasAttr<UnavailableAttr>()) {
+ FD->addAttr(UnavailableAttr::CreateImplicit(Context, "",
+ UnavailableAttr::IR_ARCFieldWithOwnership, loc));
+ }
+ } else {
+ Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
+ << T->isBlockPointerType() << Record->getTagKind();
+ }
+ ObjCFieldLifetimeErrReported = true;
+ }
} else if (getLangOpts().ObjC &&
getLangOpts().getGC() != LangOptions::NonGC &&
Record && !Record->hasObjectMember()) {
@@ -16391,23 +16130,14 @@
if (Record && !getLangOpts().CPlusPlus && !FD->hasAttr<UnavailableAttr>()) {
QualType FT = FD->getType();
- if (FT.isNonTrivialToPrimitiveDefaultInitialize()) {
+ if (FT.isNonTrivialToPrimitiveDefaultInitialize())
Record->setNonTrivialToPrimitiveDefaultInitialize(true);
- if (FT.hasNonTrivialToPrimitiveDefaultInitializeCUnion() ||
- Record->isUnion())
- Record->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(true);
- }
QualType::PrimitiveCopyKind PCK = FT.isNonTrivialToPrimitiveCopy();
- if (PCK != QualType::PCK_Trivial && PCK != QualType::PCK_VolatileTrivial) {
+ if (PCK != QualType::PCK_Trivial && PCK != QualType::PCK_VolatileTrivial)
Record->setNonTrivialToPrimitiveCopy(true);
- if (FT.hasNonTrivialToPrimitiveCopyCUnion() || Record->isUnion())
- Record->setHasNonTrivialToPrimitiveCopyCUnion(true);
- }
if (FT.isDestructedType()) {
Record->setNonTrivialToPrimitiveDestroy(true);
Record->setParamDestroyedInCallee(true);
- if (FT.hasNonTrivialToPrimitiveDestructCUnion() || Record->isUnion())
- Record->setHasNonTrivialToPrimitiveDestructCUnion(true);
}
if (const auto *RT = FT->getAs<RecordType>()) {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 8f5a892..52fa932 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -6076,7 +6076,7 @@
ILE->setInit(i, ConstantExpr::Create(Context, Init));
}
- auto *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
+ Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
VK, LiteralExpr, isFileScope);
if (isFileScope) {
if (!LiteralExpr->isTypeDependent() &&
@@ -6094,19 +6094,6 @@
return ExprError();
}
- // Compound literals that have automatic storage duration are destroyed at
- // the end of the scope. Emit diagnostics if it is or contains a C union type
- // that is non-trivial to destruct.
- if (!isFileScope)
- if (E->getType().hasNonTrivialToPrimitiveDestructCUnion())
- checkNonTrivialCUnion(E->getType(), E->getExprLoc(),
- NTCUC_CompoundLiteral, NTCUK_Destruct);
-
- if (E->getType().hasNonTrivialToPrimitiveDefaultInitializeCUnion() ||
- E->getType().hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnionInInitializer(E->getInitializer(),
- E->getInitializer()->getExprLoc());
-
return MaybeBindToTemporary(E);
}
@@ -12556,10 +12543,6 @@
if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
if (VD->hasLocalStorage() && getCurScope()->isDeclScope(VD))
BE->getBlockDecl()->setCanAvoidCopyToHeap();
-
- if (LHS.get()->getType().hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(LHS.get()->getType(), LHS.get()->getExprLoc(),
- NTCUC_Assignment, NTCUK_Copy);
}
RecordModifiableNonNullParam(*this, LHS.get());
break;
@@ -13972,11 +13955,6 @@
!BD->isDependentContext())
computeNRVO(Body, BSI);
- if (RetTy.hasNonTrivialToPrimitiveDestructCUnion() ||
- RetTy.hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(RetTy, BD->getCaretLocation(), NTCUC_FunctionReturn,
- NTCUK_Destruct|NTCUK_Copy);
-
PopDeclContext();
// Pop the block scope now but keep it alive to the end of this function.
@@ -16228,15 +16206,6 @@
}
ExprResult Sema::CheckLValueToRValueConversionOperand(Expr *E) {
- // Check whether the operand is or contains an object of non-trivial C union
- // type.
- if (E->getType().isVolatileQualified() &&
- (E->getType().hasNonTrivialToPrimitiveDestructCUnion() ||
- E->getType().hasNonTrivialToPrimitiveCopyCUnion()))
- checkNonTrivialCUnion(E->getType(), E->getExprLoc(),
- Sema::NTCUC_LValueToRValueVolatile,
- NTCUK_Destruct|NTCUK_Copy);
-
// C++2a [basic.def.odr]p4:
// [...] an expression of non-volatile-qualified non-class type to which
// the lvalue-to-rvalue conversion is applied [...]
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 29acf61..62ff33a 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -2456,11 +2456,6 @@
return true;
}
- if (T.hasNonTrivialToPrimitiveDestructCUnion() ||
- T.hasNonTrivialToPrimitiveCopyCUnion())
- checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn,
- NTCUK_Destruct|NTCUK_Copy);
-
return false;
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 3cac82a..b40e3cf 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -794,9 +794,6 @@
RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt());
RD->setNonTrivialToPrimitiveCopy(Record.readInt());
RD->setNonTrivialToPrimitiveDestroy(Record.readInt());
- RD->setHasNonTrivialToPrimitiveDefaultInitializeCUnion(Record.readInt());
- RD->setHasNonTrivialToPrimitiveDestructCUnion(Record.readInt());
- RD->setHasNonTrivialToPrimitiveCopyCUnion(Record.readInt());
RD->setParamDestroyedInCallee(Record.readInt());
RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind)Record.readInt());
return Redecl;
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index b713155..3d9dd71 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -476,9 +476,6 @@
Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize());
Record.push_back(D->isNonTrivialToPrimitiveCopy());
Record.push_back(D->isNonTrivialToPrimitiveDestroy());
- Record.push_back(D->hasNonTrivialToPrimitiveDefaultInitializeCUnion());
- Record.push_back(D->hasNonTrivialToPrimitiveDestructCUnion());
- Record.push_back(D->hasNonTrivialToPrimitiveCopyCUnion());
Record.push_back(D->isParamDestroyedInCallee());
Record.push_back(D->getArgPassingRestrictions());
@@ -2002,12 +1999,6 @@
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
// isNonTrivialToPrimitiveDestroy
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // hasNonTrivialToPrimitiveDefaultInitializeCUnion
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // hasNonTrivialToPrimitiveDestructCUnion
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
- // hasNonTrivialToPrimitiveCopyCUnion
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
// isParamDestroyedInCallee
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1));
// getArgPassingRestrictions