diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 330 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 33 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 5 |
4 files changed, 34 insertions, 352 deletions
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 11fed28b52d..3941643893a 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -1658,24 +1658,12 @@ static void markEscapingByrefs(const FunctionScopeInfo &FSI, Sema &S) { // 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 2602e52bc45..1c7b2b0ae27 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 @@ NamedDecl *Sema::ActOnVariableDeclarator( 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 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << 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 @@ bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, 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 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { 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 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { 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 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, 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 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // 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 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, 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 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, 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 8f5a892b9a2..52fa932eee8 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6076,7 +6076,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, 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 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, 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 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, 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 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, !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 @@ static ExprResult rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E, } 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 29acf6177eb..62ff33ae7e2 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2456,11 +2456,6 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) { return true; } - if (T.hasNonTrivialToPrimitiveDestructCUnion() || - T.hasNonTrivialToPrimitiveCopyCUnion()) - checkNonTrivialCUnion(T, Loc, NTCUC_FunctionReturn, - NTCUK_Destruct|NTCUK_Copy); - return false; } |

