From 84745677f64863e025a6733cb29d0b94bc3a6ae2 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Wed, 7 Jul 2010 23:37:33 +0000 Subject: [PATCH] Revert r107828 and r107827, the fix for PR7556, which seems to be breaking bootstrap on Linux. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107837 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprCXX.h | 27 +++++++++------ include/clang/AST/RecursiveASTVisitor.h | 2 +- include/clang/Basic/DiagnosticSemaKinds.td | 3 -- include/clang/Basic/StmtNodes.td | 2 +- include/clang/Frontend/PCHBitCodes.h | 2 +- lib/AST/ExprCXX.cpp | 6 ++-- lib/AST/ExprClassification.cpp | 2 +- lib/AST/ExprConstant.cpp | 8 ++--- lib/AST/StmtPrinter.cpp | 2 +- lib/AST/StmtProfile.cpp | 2 +- lib/Checker/GRExprEngine.cpp | 4 +-- lib/CodeGen/CGExpr.cpp | 6 ++-- lib/CodeGen/CGExprAgg.cpp | 4 +-- lib/CodeGen/CGExprCXX.cpp | 15 ++------ lib/CodeGen/CGExprComplex.cpp | 2 +- lib/CodeGen/CGExprScalar.cpp | 2 +- lib/CodeGen/CodeGenFunction.h | 2 +- lib/Frontend/PCHReaderStmt.cpp | 8 ++--- lib/Frontend/PCHWriterStmt.cpp | 6 ++-- lib/Sema/SemaExprCXX.cpp | 40 +++++++++++++--------- lib/Sema/SemaInit.cpp | 5 +-- lib/Sema/SemaStmt.cpp | 6 ++++ lib/Sema/TreeTransform.h | 12 +++---- test/CXX/class.access/p4.cpp | 5 ++- test/CodeGenCXX/default-arg-temps.cpp | 1 + test/CodeGenCXX/temporaries.cpp | 18 ---------- test/SemaCXX/warn-unused-variables.cpp | 2 +- tools/libclang/CXCursor.cpp | 2 +- 28 files changed, 93 insertions(+), 103 deletions(-) diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index aacb000860..6da32bacd3 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -822,8 +822,12 @@ public: /// /// This expression type represents a C++ "functional" cast /// (C++[expr.type.conv]) with N != 1 arguments that invokes a -/// constructor to build a temporary object. With N == 1 arguments the -/// functional cast expression will be represented by CXXFunctionalCastExpr. +/// constructor to build a temporary object. If N == 0 but no +/// constructor will be called (because the functional cast is +/// performing a value-initialized an object whose class type has no +/// user-declared constructors), CXXZeroInitValueExpr will represent +/// the functional cast. Finally, with N == 1 arguments the functional +/// cast expression will be represented by CXXFunctionalCastExpr. /// Example: /// @code /// struct X { X(int, float); } @@ -857,21 +861,22 @@ public: static bool classof(const CXXTemporaryObjectExpr *) { return true; } }; -/// CXXScalarValueInitExpr - [C++ 5.2.3p2] +/// CXXZeroInitValueExpr - [C++ 5.2.3p2] /// Expression "T()" which creates a value-initialized rvalue of type -/// T, which is a non-class type. +/// T, which is either a non-class type or a class type without any +/// user-defined constructors. /// -class CXXScalarValueInitExpr : public Expr { +class CXXZeroInitValueExpr : public Expr { SourceLocation TyBeginLoc; SourceLocation RParenLoc; public: - CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc, + CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc, SourceLocation rParenLoc ) : - Expr(CXXScalarValueInitExprClass, ty, false, false), + Expr(CXXZeroInitValueExprClass, ty, false, false), TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {} - explicit CXXScalarValueInitExpr(EmptyShell Shell) - : Expr(CXXScalarValueInitExprClass, Shell) { } + explicit CXXZeroInitValueExpr(EmptyShell Shell) + : Expr(CXXZeroInitValueExprClass, Shell) { } SourceLocation getTypeBeginLoc() const { return TyBeginLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -890,9 +895,9 @@ public: } static bool classof(const Stmt *T) { - return T->getStmtClass() == CXXScalarValueInitExprClass; + return T->getStmtClass() == CXXZeroInitValueExprClass; } - static bool classof(const CXXScalarValueInitExpr *) { return true; } + static bool classof(const CXXZeroInitValueExpr *) { return true; } // Iterators virtual child_iterator child_begin(); diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index f734c9af52..bf88aa084b 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1545,7 +1545,7 @@ bool RecursiveASTVisitor::TraverseInitListExpr(InitListExpr *S) { return true; } -DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { +DEF_TRAVERSE_STMT(CXXZeroInitValueExpr, { // This is called for code like 'return MyClass()' where MyClass // has no user-defined constructor. It's also called for 'return // int()'. We recurse on type MyClass/int. diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 0883eab003..f88a0ae664 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -509,9 +509,6 @@ def err_access_dtor_vbase : def err_access_dtor_temp : Error<"temporary of type %0 has %select{private|protected}1 destructor">, NoSFINAE; -def err_access_dtor_exception : - Error<"exception object of type %0 has %select{private|protected}1 " - "destructor">, NoSFINAE; def err_access_dtor_field : Error<"field of type %1 has %select{private|protected}2 destructor">, NoSFINAE; diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index a2f69730a0..bfdac746ce 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -95,7 +95,7 @@ def CXXNullPtrLiteralExpr : DStmt; def CXXThisExpr : DStmt; def CXXThrowExpr : DStmt; def CXXDefaultArgExpr : DStmt; -def CXXScalarValueInitExpr : DStmt; +def CXXZeroInitValueExpr : DStmt; def CXXNewExpr : DStmt; def CXXDeleteExpr : DStmt; def CXXPseudoDestructorExpr : DStmt; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 4da96044c5..f3fb053f3c 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -778,7 +778,7 @@ namespace clang { EXPR_CXX_DEFAULT_ARG, // CXXDefaultArgExpr EXPR_CXX_BIND_TEMPORARY, // CXXBindTemporaryExpr // - EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr + EXPR_CXX_ZERO_INIT_VALUE, // CXXZeroInitValueExpr EXPR_CXX_NEW, // CXXNewExpr EXPR_CXX_DELETE, // CXXDeleteExpr EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index c3c5ccc60f..08d8ae46b4 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -74,11 +74,11 @@ Stmt::child_iterator CXXDefaultArgExpr::child_end() { return child_iterator(); } -// CXXScalarValueInitExpr -Stmt::child_iterator CXXScalarValueInitExpr::child_begin() { +// CXXZeroInitValueExpr +Stmt::child_iterator CXXZeroInitValueExpr::child_begin() { return child_iterator(); } -Stmt::child_iterator CXXScalarValueInitExpr::child_end() { +Stmt::child_iterator CXXZeroInitValueExpr::child_end() { return child_iterator(); } diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 60ac347c50..4629500848 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -205,7 +205,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // Some C++ expressions are always class temporaries. case Expr::CXXConstructExprClass: case Expr::CXXTemporaryObjectExprClass: - case Expr::CXXScalarValueInitExprClass: + case Expr::CXXZeroInitValueExprClass: return Cl::CL_ClassTemporary; // Everything we haven't handled is a prvalue. diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index a963182ae8..5dae4d4475 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -938,7 +938,7 @@ public: return Success(0, E); } - bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { + bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) { return Success(0, E); } @@ -1756,7 +1756,7 @@ public: bool VisitBinaryOperator(const BinaryOperator *E); bool VisitFloatingLiteral(const FloatingLiteral *E); bool VisitCastExpr(CastExpr *E); - bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); + bool VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); bool VisitConditionalOperator(ConditionalOperator *E); bool VisitChooseExpr(const ChooseExpr *E) @@ -1952,7 +1952,7 @@ bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) { return false; } -bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType())); return true; } @@ -2410,7 +2410,7 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case Expr::IntegerLiteralClass: case Expr::CharacterLiteralClass: case Expr::CXXBoolLiteralExprClass: - case Expr::CXXScalarValueInitExprClass: + case Expr::CXXZeroInitValueExprClass: case Expr::TypesCompatibleExprClass: case Expr::UnaryTypeTraitExprClass: return NoDiag(); diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 7043c35516..964106f7d7 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1086,7 +1086,7 @@ void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) { OS << ")"; } -void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) { +void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) { OS << Node->getType().getAsString(Policy) << "()"; } diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index 2c6918677d..4b17e5262e 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -721,7 +721,7 @@ void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) { VisitCXXConstructExpr(S); } -void StmtProfiler::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *S) { +void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) { VisitExpr(S); } diff --git a/lib/Checker/GRExprEngine.cpp b/lib/Checker/GRExprEngine.cpp index 4652a4c89f..d4a410e440 100644 --- a/lib/Checker/GRExprEngine.cpp +++ b/lib/Checker/GRExprEngine.cpp @@ -655,7 +655,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) { case Stmt::CXXTryStmtClass: case Stmt::CXXTypeidExprClass: case Stmt::CXXUnresolvedConstructExprClass: - case Stmt::CXXScalarValueInitExprClass: + case Stmt::CXXZeroInitValueExprClass: case Stmt::DependentScopeDeclRefExprClass: case Stmt::UnaryTypeTraitExprClass: case Stmt::UnresolvedLookupExprClass: @@ -962,7 +962,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred, // C++ stuff we don't support yet. case Stmt::CXXExprWithTemporariesClass: case Stmt::CXXMemberCallExprClass: - case Stmt::CXXScalarValueInitExprClass: { + case Stmt::CXXZeroInitValueExprClass: { SaveAndRestore OldSink(Builder->BuildSinks); Builder->BuildSinks = true; MakeNode(Dst, Ex, Pred, GetState(Pred)); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0426a60f0c..3621dbb1ee 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -544,8 +544,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) { return EmitCXXBindTemporaryLValue(cast(E)); case Expr::CXXExprWithTemporariesClass: return EmitCXXExprWithTemporariesLValue(cast(E)); - case Expr::CXXScalarValueInitExprClass: - return EmitNullInitializationLValue(cast(E)); + case Expr::CXXZeroInitValueExprClass: + return EmitNullInitializationLValue(cast(E)); case Expr::CXXDefaultArgExprClass: return EmitLValue(cast(E)->getExpr()); case Expr::CXXTypeidExprClass: @@ -1829,7 +1829,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { } LValue CodeGenFunction::EmitNullInitializationLValue( - const CXXScalarValueInitExpr *E) { + const CXXZeroInitValueExpr *E) { QualType Ty = E->getType(); LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty)); EmitNullInitialization(LV.getAddress(), Ty); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 5a2c379df2..8cf07fd36b 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -127,7 +127,7 @@ public: void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); void VisitCXXConstructExpr(const CXXConstructExpr *E); void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E); - void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); + void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } void VisitVAArgExpr(VAArgExpr *E); @@ -557,7 +557,7 @@ void AggExprEmitter::VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { CGF.EmitCXXExprWithTemporaries(E, Val, VolatileDest, IsInitializer); } -void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +void AggExprEmitter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { llvm::Value *Val = DestPtr; if (!Val) { diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index ea1753bbc1..f2e6a11292 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -572,18 +572,9 @@ static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, } if (CXXConstructorDecl *Ctor = E->getConstructor()) { - // Per C++ [expr.new]p15, if we have an initializer, then we're performing - // direct initialization. C++ [dcl.init]p5 requires that we - // zero-initialize storage if there are no user-declared constructors. - if (E->hasInitializer() && - !Ctor->getParent()->hasUserDeclaredConstructor() && - !Ctor->getParent()->isEmpty()) - CGF.EmitNullInitialization(NewPtr, E->getAllocatedType()); - - if (!Ctor->isTrivial()) - CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, - NewPtr, E->constructor_arg_begin(), - E->constructor_arg_end()); + CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, + NewPtr, E->constructor_arg_begin(), + E->constructor_arg_end()); return; } diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp index 90b6446e0e..c2e10bf3f2 100644 --- a/lib/CodeGen/CGExprComplex.cpp +++ b/lib/CodeGen/CGExprComplex.cpp @@ -181,7 +181,7 @@ public: ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) { return CGF.EmitCXXExprWithTemporaries(E).getComplexVal(); } - ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { + ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { assert(E->getType()->isAnyComplexType() && "Expected complex type!"); QualType Elem = E->getType()->getAs()->getElementType(); llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem)); diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 1ebc2c571a..8c120faaec 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -126,7 +126,7 @@ public: Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) { return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue()); } - Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) { + Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) { return EmitNullValue(E->getType()); } Value *VisitGNUNullExpr(const GNUNullExpr *E) { diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 26fb882e56..3e4cd3bbe2 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1209,7 +1209,7 @@ public: LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E); LValue EmitConditionalOperatorLValue(const ConditionalOperator *E); LValue EmitCastLValue(const CastExpr *E); - LValue EmitNullInitializationLValue(const CXXScalarValueInitExpr *E); + LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E); llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar); diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp index d330eecb70..28641e8dfa 100644 --- a/lib/Frontend/PCHReaderStmt.cpp +++ b/lib/Frontend/PCHReaderStmt.cpp @@ -132,7 +132,7 @@ namespace clang { void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); - void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); + void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); void VisitCXXNewExpr(CXXNewExpr *E); void VisitCXXDeleteExpr(CXXDeleteExpr *E); void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); @@ -1003,7 +1003,7 @@ void PCHStmtReader::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { E->setSubExpr(Reader.ReadSubExpr()); } -void PCHStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +void PCHStmtReader::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { VisitExpr(E); E->setTypeBeginLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); E->setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); @@ -1574,8 +1574,8 @@ Stmt *PCHReader::ReadStmtFromStream(llvm::BitstreamCursor &Cursor) { S = new (Context) CXXBindTemporaryExpr(Empty); break; - case pch::EXPR_CXX_SCALAR_VALUE_INIT: - S = new (Context) CXXScalarValueInitExpr(Empty); + case pch::EXPR_CXX_ZERO_INIT_VALUE: + S = new (Context) CXXZeroInitValueExpr(Empty); break; case pch::EXPR_CXX_NEW: S = new (Context) CXXNewExpr(Empty); diff --git a/lib/Frontend/PCHWriterStmt.cpp b/lib/Frontend/PCHWriterStmt.cpp index 00cebf15eb..91f9353ed0 100644 --- a/lib/Frontend/PCHWriterStmt.cpp +++ b/lib/Frontend/PCHWriterStmt.cpp @@ -132,7 +132,7 @@ namespace clang { void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E); void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); - void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); + void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E); void VisitCXXNewExpr(CXXNewExpr *E); void VisitCXXDeleteExpr(CXXDeleteExpr *E); void VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E); @@ -1007,11 +1007,11 @@ void PCHStmtWriter::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { Code = pch::EXPR_CXX_BIND_TEMPORARY; } -void PCHStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +void PCHStmtWriter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { VisitExpr(E); Writer.AddSourceLocation(E->getTypeBeginLoc(), Record); Writer.AddSourceLocation(E->getRParenLoc(), Record); - Code = pch::EXPR_CXX_SCALAR_VALUE_INIT; + Code = pch::EXPR_CXX_ZERO_INIT_VALUE; } void PCHStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) { diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 180b5911bf..021b4afb25 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -460,7 +460,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) { MarkDeclarationReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, - PDiag(diag::err_access_dtor_exception) << Ty); + PDiag(diag::err_access_dtor_temp) << Ty); return false; } @@ -546,19 +546,27 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, RParenLoc)); } - if (Ty->isRecordType()) { - InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty); - InitializationKind Kind - = NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(), - LParenLoc, RParenLoc) - : InitializationKind::CreateValue(TypeRange.getBegin(), - LParenLoc, RParenLoc); - InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); - OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, - move(exprs)); - - // FIXME: Improve AST representation? - return move(Result); + if (const RecordType *RT = Ty->getAs()) { + CXXRecordDecl *Record = cast(RT->getDecl()); + + if (NumExprs > 1 || !Record->hasTrivialConstructor() || + !Record->hasTrivialDestructor()) { + InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty); + InitializationKind Kind + = NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(), + LParenLoc, RParenLoc) + : InitializationKind::CreateValue(TypeRange.getBegin(), + LParenLoc, RParenLoc); + InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); + OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, + move(exprs)); + + // FIXME: Improve AST representation? + return move(Result); + } + + // Fall through to value-initialize an object of class type that + // doesn't have a user-declared default constructor. } // C++ [expr.type.conv]p1: @@ -577,7 +585,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep, // rvalue of the specified type, which is value-initialized. // exprs.release(); - return Owned(new (Context) CXXScalarValueInitExpr(Ty, TyBeginLoc, RParenLoc)); + return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc)); } @@ -1984,7 +1992,7 @@ QualType Sema::CheckPointerToMemberOperands( BasePath); } - if (isa(rex->IgnoreParens())) { + if (isa(rex->IgnoreParens())) { // Diagnose use of pointer-to-member type which when used as // the functional cast in a pointer-to-member expression. Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 5571c1b382..536222c37f 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2772,7 +2772,8 @@ static void TryValueInitialization(Sema &S, // zero-initialized and, if T’s implicitly-declared default // constructor is non-trivial, that constructor is called. if ((ClassDecl->getTagKind() == TTK_Class || - ClassDecl->getTagKind() == TTK_Struct)) { + ClassDecl->getTagKind() == TTK_Struct) && + !ClassDecl->hasTrivialConstructor()) { Sequence.AddZeroInitializationStep(Entity.getType()); return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); } @@ -3837,7 +3838,7 @@ InitializationSequence::Perform(Sema &S, } else if (Kind.getKind() == InitializationKind::IK_Value && S.getLangOptions().CPlusPlus && !Kind.isImplicitValueInit()) { - CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type, + CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type, Kind.getRange().getBegin(), Kind.getRange().getEnd())); } else { diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 9c8f48bfea..1abcf205dd 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -92,6 +92,12 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (const CXXExprWithTemporaries *Temps = dyn_cast(E)) E = Temps->getSubExpr(); + if (const CXXZeroInitValueExpr *Zero = dyn_cast(E)) { + if (const RecordType *RecordT = Zero->getType()->getAs()) + if (CXXRecordDecl *RecordD = dyn_cast(RecordT->getDecl())) + if (!RecordD->hasTrivialDestructor()) + return; + } if (const CallExpr *CE = dyn_cast(E)) { if (E->getType()->isVoidType()) diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 95e304eb44..b2a405934c 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1577,7 +1577,7 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - OwningExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc, + OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc, SourceLocation LParenLoc, QualType T, SourceLocation RParenLoc) { @@ -5219,7 +5219,7 @@ TreeTransform::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) { template Sema::OwningExprResult -TreeTransform::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) { +TreeTransform::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) { TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName()); QualType T = getDerived().TransformType(E->getType()); @@ -5230,10 +5230,10 @@ TreeTransform::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr * T == E->getType()) return SemaRef.Owned(E->Retain()); - return getDerived().RebuildCXXScalarValueInitExpr(E->getTypeBeginLoc(), - /*FIXME:*/E->getTypeBeginLoc(), - T, - E->getRParenLoc()); + return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(), + /*FIXME:*/E->getTypeBeginLoc(), + T, + E->getRParenLoc()); } template diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 90a1449610..552c52f977 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -423,7 +423,6 @@ namespace test15 { // PR7281 namespace test16 { - class A { ~A(); }; // expected-note 2{{declared private here}} - void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} \ - // expected-error{{exception object of type 'test16::A' has private destructor}} + class A { ~A(); }; // expected-note {{declared private here}} + void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}} } diff --git a/test/CodeGenCXX/default-arg-temps.cpp b/test/CodeGenCXX/default-arg-temps.cpp index c4419850f1..e4a06770cd 100644 --- a/test/CodeGenCXX/default-arg-temps.cpp +++ b/test/CodeGenCXX/default-arg-temps.cpp @@ -44,6 +44,7 @@ class obj{ int a; float b; double d; }; // CHECK: define void @_Z1hv() void h() { // CHECK: call void @llvm.memset.p0i8.i64( + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64( obj o = obj(); } diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 9a397abfc0..eb543cb545 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -320,21 +320,3 @@ namespace UserConvertToValue { f(1); } } - -namespace PR7556 { - struct A { ~A(); }; - struct B { int i; ~B(); }; - struct C { int C::*pm; ~C(); }; - // CHECK: define void @_ZN6PR75563fooEv() - void foo() { - // CHECK: call void @_ZN6PR75561AD1Ev - A(); - // CHECK: call void @llvm.memset.p0i8.i64 - // CHECK: call void @_ZN6PR75561BD1Ev - B(); - // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 - // CHECK: call void @_ZN6PR75561CD1Ev - C(); - // CHECK-NEXT: ret void - } -} diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp index 6992cdcd09..5ef7e7002f 100644 --- a/test/SemaCXX/warn-unused-variables.cpp +++ b/test/SemaCXX/warn-unused-variables.cpp @@ -26,7 +26,7 @@ namespace PR5531 { }; void test() { - A(); + A(); // expected-warning{{expression result unused}} B(17); C(); } diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp index be3623f6e9..0f9f79da69 100644 --- a/tools/libclang/CXCursor.cpp +++ b/tools/libclang/CXCursor.cpp @@ -174,7 +174,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) { case Stmt::CXXThisExprClass: case Stmt::CXXThrowExprClass: case Stmt::CXXDefaultArgExprClass: - case Stmt::CXXScalarValueInitExprClass: + case Stmt::CXXZeroInitValueExprClass: case Stmt::CXXNewExprClass: case Stmt::CXXDeleteExprClass: case Stmt::CXXPseudoDestructorExprClass: -- 2.40.0