]> granicus.if.org Git - clang/commitdiff
Reinstate the fix for PR7556. A silly use of isTrivial() was
authorDouglas Gregor <dgregor@apple.com>
Thu, 8 Jul 2010 06:14:04 +0000 (06:14 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 8 Jul 2010 06:14:04 +0000 (06:14 +0000)
suppressing copies of objects with trivial copy constructors.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107857 91177308-0d34-0410-b5e6-96231b3b80d8

29 files changed:
include/clang/AST/ExprCXX.h
include/clang/AST/RecursiveASTVisitor.h
include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Basic/StmtNodes.td
include/clang/Frontend/PCHBitCodes.h
lib/AST/ASTContext.cpp
lib/AST/ExprCXX.cpp
lib/AST/ExprClassification.cpp
lib/AST/ExprConstant.cpp
lib/AST/StmtPrinter.cpp
lib/AST/StmtProfile.cpp
lib/Checker/GRExprEngine.cpp
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprCXX.cpp
lib/CodeGen/CGExprComplex.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
lib/Frontend/PCHReaderStmt.cpp
lib/Frontend/PCHWriterStmt.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaInit.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/TreeTransform.h
test/CXX/class.access/p4.cpp
test/CodeGenCXX/default-arg-temps.cpp
test/CodeGenCXX/temporaries.cpp
test/SemaCXX/warn-unused-variables.cpp
tools/libclang/CXCursor.cpp

index 6da32bacd304e65b2a2d68584c1460a00005437b..aacb000860043d39276472a54619128cb5a83b55 100644 (file)
@@ -822,12 +822,8 @@ 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. 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.
+/// constructor to build a temporary object. With N == 1 arguments the 
+/// functional cast expression will be represented by CXXFunctionalCastExpr.
 /// Example:
 /// @code
 /// struct X { X(int, float); }
@@ -861,22 +857,21 @@ public:
   static bool classof(const CXXTemporaryObjectExpr *) { return true; }
 };
 
-/// CXXZeroInitValueExpr - [C++ 5.2.3p2]
+/// CXXScalarValueInitExpr - [C++ 5.2.3p2]
 /// Expression "T()" which creates a value-initialized rvalue of type
-/// T, which is either a non-class type or a class type without any
-/// user-defined constructors.
+/// T, which is a non-class type.
 ///
-class CXXZeroInitValueExpr : public Expr {
+class CXXScalarValueInitExpr : public Expr {
   SourceLocation TyBeginLoc;
   SourceLocation RParenLoc;
 
 public:
-  CXXZeroInitValueExpr(QualType ty, SourceLocation tyBeginLoc,
+  CXXScalarValueInitExpr(QualType ty, SourceLocation tyBeginLoc,
                        SourceLocation rParenLoc ) :
-    Expr(CXXZeroInitValueExprClass, ty, false, false),
+    Expr(CXXScalarValueInitExprClass, ty, false, false),
     TyBeginLoc(tyBeginLoc), RParenLoc(rParenLoc) {}
-  explicit CXXZeroInitValueExpr(EmptyShell Shell)
-    : Expr(CXXZeroInitValueExprClass, Shell) { }
+  explicit CXXScalarValueInitExpr(EmptyShell Shell)
+    : Expr(CXXScalarValueInitExprClass, Shell) { }
 
   SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
   SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -895,9 +890,9 @@ public:
   }
 
   static bool classof(const Stmt *T) {
-    return T->getStmtClass() == CXXZeroInitValueExprClass;
+    return T->getStmtClass() == CXXScalarValueInitExprClass;
   }
-  static bool classof(const CXXZeroInitValueExpr *) { return true; }
+  static bool classof(const CXXScalarValueInitExpr *) { return true; }
 
   // Iterators
   virtual child_iterator child_begin();
index bf88aa084b2fd3a664826936cbfca81ca6367a29..f734c9af52174b5aa056691135f4b0c41116208e 100644 (file)
@@ -1545,7 +1545,7 @@ bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
   return true;
 }
 
-DEF_TRAVERSE_STMT(CXXZeroInitValueExpr, {
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
     // 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.
index f88a0ae66415c6fd8f51cb4e429548d07e3fa3a9..0883eab0034bc16299fcef56622db1b6d40da237 100644 (file)
@@ -509,6 +509,9 @@ 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;
index bfdac746cea78ca79964d0949cb24d90a4d1df97..a2f69730a010e27a2e4be8022111533279317ad9 100644 (file)
@@ -95,7 +95,7 @@ def CXXNullPtrLiteralExpr : DStmt<Expr>;
 def CXXThisExpr : DStmt<Expr>;
 def CXXThrowExpr : DStmt<Expr>;
 def CXXDefaultArgExpr : DStmt<Expr>;
-def CXXZeroInitValueExpr : DStmt<Expr>;
+def CXXScalarValueInitExpr : DStmt<Expr>;
 def CXXNewExpr : DStmt<Expr>;
 def CXXDeleteExpr : DStmt<Expr>;
 def CXXPseudoDestructorExpr : DStmt<Expr>;
index f3fb053f3cd379f265e8d8254126fcaa716e0381..4da96044c5d1b7e6ac81770bd5f67dc4b2cb4ef3 100644 (file)
@@ -778,7 +778,7 @@ namespace clang {
       EXPR_CXX_DEFAULT_ARG,       // CXXDefaultArgExpr
       EXPR_CXX_BIND_TEMPORARY,    // CXXBindTemporaryExpr
       //
-      EXPR_CXX_ZERO_INIT_VALUE,   // CXXZeroInitValueExpr
+      EXPR_CXX_SCALAR_VALUE_INIT, // CXXScalarValueInitExpr
       EXPR_CXX_NEW,               // CXXNewExpr
       EXPR_CXX_DELETE,            // CXXDeleteExpr
       EXPR_CXX_PSEUDO_DESTRUCTOR, // CXXPseudoDestructorExpr
index 4d950c0bfbcee1b4a5e3bb8eeb1ee489046c6be6..d41051f5dcad7210ea11018a6f6f4fba8916e294 100644 (file)
@@ -261,7 +261,7 @@ void ASTContext::PrintStats() const {
 #include "clang/AST/TypeNodes.def"
 
   fprintf(stderr, "Total bytes = %d\n", int(TotalBytes));
-
+  
   // Implicit special member functions.
   fprintf(stderr, "  %u/%u implicit default constructors created\n",
           NumImplicitDefaultConstructorsDeclared, 
@@ -282,6 +282,9 @@ void ASTContext::PrintStats() const {
     fprintf(stderr, "\n");
     ExternalSource->PrintStats();
   }
+  
+  if (!FreeMemory)
+    BumpAlloc.PrintStats();
 }
 
 
index 08d8ae46b460188c68dee203b5bc9799ac628b3c..c3c5ccc60fab96caa54f3f720381ddb1a5a4cb14 100644 (file)
@@ -74,11 +74,11 @@ Stmt::child_iterator CXXDefaultArgExpr::child_end() {
   return child_iterator();
 }
 
-// CXXZeroInitValueExpr
-Stmt::child_iterator CXXZeroInitValueExpr::child_begin() {
+// CXXScalarValueInitExpr
+Stmt::child_iterator CXXScalarValueInitExpr::child_begin() {
   return child_iterator();
 }
-Stmt::child_iterator CXXZeroInitValueExpr::child_end() {
+Stmt::child_iterator CXXScalarValueInitExpr::child_end() {
   return child_iterator();
 }
 
index 4629500848b61c1a51b8920d9542ca42c0310cf6..60ac347c50fb0697903c3d59ba760f5b22e95eea 100644 (file)
@@ -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::CXXZeroInitValueExprClass:
+  case Expr::CXXScalarValueInitExprClass:
     return Cl::CL_ClassTemporary;
 
     // Everything we haven't handled is a prvalue.
index 5dae4d447582ae68608a7ab2d6445efa8d02c849..a963182ae88b9eff012b68b242e8411e47a2249b 100644 (file)
@@ -938,7 +938,7 @@ public:
     return Success(0, E);
   }
 
-  bool VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+  bool VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *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 VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  bool VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
   bool VisitConditionalOperator(ConditionalOperator *E);
 
   bool VisitChooseExpr(const ChooseExpr *E)
@@ -1952,7 +1952,7 @@ bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
   return false;
 }
 
-bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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::CXXZeroInitValueExprClass:
+  case Expr::CXXScalarValueInitExprClass:
   case Expr::TypesCompatibleExprClass:
   case Expr::UnaryTypeTraitExprClass:
     return NoDiag();
index 964106f7d7e347fdc4d9570fc6085508e0247e74..7043c35516289e4332b3f20f1ee398ed5d1b0f3e 100644 (file)
@@ -1086,7 +1086,7 @@ void StmtPrinter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *Node) {
   OS << ")";
 }
 
-void StmtPrinter::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *Node) {
+void StmtPrinter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *Node) {
   OS << Node->getType().getAsString(Policy) << "()";
 }
 
index 4b17e5262e3015e905e201057bd66c6d565317aa..2c6918677d0a9584f4a6f794086795c8a909a336 100644 (file)
@@ -721,7 +721,7 @@ void StmtProfiler::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *S) {
   VisitCXXConstructExpr(S);
 }
 
-void StmtProfiler::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *S) {
+void StmtProfiler::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *S) {
   VisitExpr(S);
 }
 
index d4a410e440207d5f1b58f8877b5a53dca16aeed9..4652a4c89ff3bee4dcb30fd29d77652c093a10c2 100644 (file)
@@ -655,7 +655,7 @@ void GRExprEngine::Visit(Stmt* S, ExplodedNode* Pred, ExplodedNodeSet& Dst) {
     case Stmt::CXXTryStmtClass:
     case Stmt::CXXTypeidExprClass:
     case Stmt::CXXUnresolvedConstructExprClass:
-    case Stmt::CXXZeroInitValueExprClass:
+    case Stmt::CXXScalarValueInitExprClass:
     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::CXXZeroInitValueExprClass: {
+    case Stmt::CXXScalarValueInitExprClass: {
       SaveAndRestore<bool> OldSink(Builder->BuildSinks);
       Builder->BuildSinks = true;
       MakeNode(Dst, Ex, Pred, GetState(Pred));
index 3621dbb1ee8be816fbcd162666c39abecd6169b9..0426a60f0c37fc517a730834523c6e6d0d3a7ff1 100644 (file)
@@ -544,8 +544,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
     return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
   case Expr::CXXExprWithTemporariesClass:
     return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
-  case Expr::CXXZeroInitValueExprClass:
-    return EmitNullInitializationLValue(cast<CXXZeroInitValueExpr>(E));
+  case Expr::CXXScalarValueInitExprClass:
+    return EmitNullInitializationLValue(cast<CXXScalarValueInitExpr>(E));
   case Expr::CXXDefaultArgExprClass:
     return EmitLValue(cast<CXXDefaultArgExpr>(E)->getExpr());
   case Expr::CXXTypeidExprClass:
@@ -1829,7 +1829,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
 }
 
 LValue CodeGenFunction::EmitNullInitializationLValue(
-                                              const CXXZeroInitValueExpr *E) {
+                                              const CXXScalarValueInitExpr *E) {
   QualType Ty = E->getType();
   LValue LV = LValue::MakeAddr(CreateMemTemp(Ty), MakeQualifiers(Ty));
   EmitNullInitialization(LV.getAddress(), Ty);
index 35b7016ab3509ae3d1499d8a510c09126d8e5b8a..20722f7799cfb55d93141447ea4a7cadf58193e6 100644 (file)
@@ -127,7 +127,7 @@ public:
   void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
   void VisitCXXConstructExpr(const CXXConstructExpr *E);
   void VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E);
-  void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+  void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+void AggExprEmitter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   llvm::Value *Val = DestPtr;
 
   if (!Val) {
index f2e6a11292b7ad053c381419dd27d464b837722b..69e5f0ef4be894ac725a94f62ed471c8ba4b5f2b 100644 (file)
@@ -572,6 +572,14 @@ 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());
+      
     CGF.EmitCXXConstructorCall(Ctor, Ctor_Complete, /*ForVirtualBase=*/false, 
                                NewPtr, E->constructor_arg_begin(),
                                E->constructor_arg_end());
index c2e10bf3f25dfad066cb40781f5de2bfc8e02b18..90b6446e0e655b87d91af35fa4a791a05ada334c 100644 (file)
@@ -181,7 +181,7 @@ public:
   ComplexPairTy VisitCXXExprWithTemporaries(CXXExprWithTemporaries *E) {
     return CGF.EmitCXXExprWithTemporaries(E).getComplexVal();
   }
-  ComplexPairTy VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+  ComplexPairTy VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
     assert(E->getType()->isAnyComplexType() && "Expected complex type!");
     QualType Elem = E->getType()->getAs<ComplexType>()->getElementType();
     llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
index 8c120faaec877aa66524c5144de487d1e8102f40..1ebc2c571a017cc62f95d5c86ddb979091a79f57 100644 (file)
@@ -126,7 +126,7 @@ public:
   Value *VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
     return llvm::ConstantInt::get(ConvertType(E->getType()), E->getValue());
   }
-  Value *VisitCXXZeroInitValueExpr(const CXXZeroInitValueExpr *E) {
+  Value *VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E) {
     return EmitNullValue(E->getType());
   }
   Value *VisitGNUNullExpr(const GNUNullExpr *E) {
index 3e4cd3bbe2911351cb3ef9cbba86e75c58e42f81..26fb882e56f93d6255aac49a387b0e010c4e62b1 100644 (file)
@@ -1209,7 +1209,7 @@ public:
   LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E);
   LValue EmitConditionalOperatorLValue(const ConditionalOperator *E);
   LValue EmitCastLValue(const CastExpr *E);
-  LValue EmitNullInitializationLValue(const CXXZeroInitValueExpr *E);
+  LValue EmitNullInitializationLValue(const CXXScalarValueInitExpr *E);
   
   llvm::Value *EmitIvarOffset(const ObjCInterfaceDecl *Interface,
                               const ObjCIvarDecl *Ivar);
index 28641e8dfa1d9a886e00fb3b4d35fb14dadb788d..d330eecb70de6826c7005c47f2a3c54a0d4a9c32 100644 (file)
@@ -132,7 +132,7 @@ namespace clang {
     void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
     void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
     
-    void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+    void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+void PCHStmtReader::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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_ZERO_INIT_VALUE:
-      S = new (Context) CXXZeroInitValueExpr(Empty);
+    case pch::EXPR_CXX_SCALAR_VALUE_INIT:
+      S = new (Context) CXXScalarValueInitExpr(Empty);
       break;
     case pch::EXPR_CXX_NEW:
       S = new (Context) CXXNewExpr(Empty);
index 91f9353ed0c4d684a0a2eb47d58521b15a0e3cc8..00cebf15ebb6be04ffc9450c2e114821fab64f63 100644 (file)
@@ -132,7 +132,7 @@ namespace clang {
     void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
     void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
 
-    void VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E);
+    void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *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::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+void PCHStmtWriter::VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   VisitExpr(E);
   Writer.AddSourceLocation(E->getTypeBeginLoc(), Record);
   Writer.AddSourceLocation(E->getRParenLoc(), Record);
-  Code = pch::EXPR_CXX_ZERO_INIT_VALUE;
+  Code = pch::EXPR_CXX_SCALAR_VALUE_INIT;
 }
 
 void PCHStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
index 021b4afb25d14eb88a0d1898729e8159481af993..180b5911bfc42485152d7d67822622f9ee6a52c1 100644 (file)
@@ -460,7 +460,7 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
 
   MarkDeclarationReferenced(E->getExprLoc(), Destructor);
   CheckDestructorAccess(E->getExprLoc(), Destructor,
-                        PDiag(diag::err_access_dtor_temp) << Ty);
+                        PDiag(diag::err_access_dtor_exception) << Ty);
   return false;
 }
 
@@ -546,27 +546,19 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
                                                      RParenLoc));
   }
 
-  if (const RecordType *RT = Ty->getAs<RecordType>()) {
-    CXXRecordDecl *Record = cast<CXXRecordDecl>(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.
+  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);
   }
 
   // C++ [expr.type.conv]p1:
@@ -585,7 +577,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
   // rvalue of the specified type, which is value-initialized.
   //
   exprs.release();
-  return Owned(new (Context) CXXZeroInitValueExpr(Ty, TyBeginLoc, RParenLoc));
+  return Owned(new (Context) CXXScalarValueInitExpr(Ty, TyBeginLoc, RParenLoc));
 }
 
 
@@ -1992,7 +1984,7 @@ QualType Sema::CheckPointerToMemberOperands(
                       BasePath);
   }
 
-  if (isa<CXXZeroInitValueExpr>(rex->IgnoreParens())) {
+  if (isa<CXXScalarValueInitExpr>(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;
index 536222c37f011ac3d6fda270af58412abefa4698..5571c1b3824e6d0097274de93eba805506e599da 100644 (file)
@@ -2772,8 +2772,7 @@ 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->hasTrivialConstructor()) {
+           ClassDecl->getTagKind() == TTK_Struct)) {
         Sequence.AddZeroInitializationStep(Entity.getType());
         return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence);        
       }
@@ -3838,7 +3837,7 @@ InitializationSequence::Perform(Sema &S,
       } else if (Kind.getKind() == InitializationKind::IK_Value &&
                  S.getLangOptions().CPlusPlus &&
                  !Kind.isImplicitValueInit()) {
-        CurInit = S.Owned(new (S.Context) CXXZeroInitValueExpr(Step->Type,
+        CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type,
                                                    Kind.getRange().getBegin(),
                                                     Kind.getRange().getEnd()));
       } else {
index 1abcf205dd941fca57b02516c733cd2b38951ebd..9c8f48bfea17276535267ef5b7f611d9321a23b6 100644 (file)
@@ -92,12 +92,6 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) {
   
   if (const CXXExprWithTemporaries *Temps = dyn_cast<CXXExprWithTemporaries>(E))
     E = Temps->getSubExpr();
-  if (const CXXZeroInitValueExpr *Zero = dyn_cast<CXXZeroInitValueExpr>(E)) {
-    if (const RecordType *RecordT = Zero->getType()->getAs<RecordType>())
-      if (CXXRecordDecl *RecordD = dyn_cast<CXXRecordDecl>(RecordT->getDecl()))
-        if (!RecordD->hasTrivialDestructor())
-          return;
-  }
       
   if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
     if (E->getType()->isVoidType())
index b2a405934c59bfeb1b532aa4ca6e84800c0a163a..95e304eb44d9af645acce0dfe9d24ce9dfc7b2c1 100644 (file)
@@ -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 RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
+  OwningExprResult RebuildCXXScalarValueInitExpr(SourceLocation TypeStartLoc,
                                                SourceLocation LParenLoc,
                                                QualType T,
                                                SourceLocation RParenLoc) {
@@ -5219,7 +5219,7 @@ TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
 
 template<typename Derived>
 Sema::OwningExprResult
-TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
+TreeTransform<Derived>::TransformCXXScalarValueInitExpr(CXXScalarValueInitExpr *E) {
   TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
 
   QualType T = getDerived().TransformType(E->getType());
@@ -5230,10 +5230,10 @@ TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
       T == E->getType())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
-                                                /*FIXME:*/E->getTypeBeginLoc(),
-                                                  T,
-                                                  E->getRParenLoc());
+  return getDerived().RebuildCXXScalarValueInitExpr(E->getTypeBeginLoc(),
+                                                 /*FIXME:*/E->getTypeBeginLoc(),
+                                                    T,
+                                                    E->getRParenLoc());
 }
 
 template<typename Derived>
index 552c52f977eccd9e7dafcfc7f414d2d6022e996e..90a1449610f31b5c27a2452f426312f604e23c6a 100644 (file)
@@ -423,6 +423,7 @@ namespace test15 {
 
 // PR7281
 namespace test16 {
-  class A { ~A(); }; // expected-note {{declared private here}}
-  void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}}
+  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}}
 }
index e4a06770cd9bb5ae6cf701d0a77d225ea23c0324..c4419850f12d4dfc08468eda355cd7aa0105c158 100644 (file)
@@ -44,7 +44,6 @@ 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();
 }
 
index eb543cb5455254f7c12f6fcf1d63e6602bbce482..9a397abfc0cfb65e4e6274959ad1a3e5b1cc83e6 100644 (file)
@@ -320,3 +320,21 @@ 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
+  }
+}
index 5ef7e7002f65abbd10720f996a3a71c841258032..6992cdcd0902a73299de5f4f005d3c4d152eef44 100644 (file)
@@ -26,7 +26,7 @@ namespace PR5531 {
   };
 
   void test() {
-    A(); // expected-warning{{expression result unused}}
+    A();
     B(17);
     C();
   }
index 0f9f79da69d0495453a030e43907646cd0c01c9d..be3623f6e9e2ce2d4d1560c2a42f811f9d061366 100644 (file)
@@ -174,7 +174,7 @@ CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, ASTUnit *TU) {
   case Stmt::CXXThisExprClass:            
   case Stmt::CXXThrowExprClass:           
   case Stmt::CXXDefaultArgExprClass:      
-  case Stmt::CXXZeroInitValueExprClass:   
+  case Stmt::CXXScalarValueInitExprClass:   
   case Stmt::CXXNewExprClass:             
   case Stmt::CXXDeleteExprClass:          
   case Stmt::CXXPseudoDestructorExprClass: