diff options
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3001be23cf..7f00981d34 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6083,7 +6083,7 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, ILE->setInit(i, ConstantExpr::Create(Context, Init)); } - Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, + auto *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr, isFileScope); if (isFileScope) { if (!LiteralExpr->isTypeDependent() && @@ -6101,6 +6101,19 @@ 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); } @@ -12782,6 +12795,10 @@ 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; @@ -14194,6 +14211,11 @@ 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. @@ -16464,6 +16486,15 @@ 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 [...] |