From: Anders Carlsson Date: Thu, 16 Apr 2009 23:50:50 +0000 (+0000) Subject: If a class has a non-trivial constructor that doesn't take any arguments, we will... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=930e8d0c2f0b30da3a6a9c440503976d8250e7cf;p=clang If a class has a non-trivial constructor that doesn't take any arguments, we will now make an implicit CXXTemporaryObjectExpr. So struct S { S(); }; void f() { S s; } 's' here will implicitly be declared as. S s = S(); git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69326 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index fd708516f4..ef20a6a330 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1418,6 +1418,13 @@ public: SourceLocation *CommaLocs, SourceLocation RParenLoc); + /// InitializeVarWithConstructor - Creates an implicit + /// CXXTemporaryObjectExpr and sets it as the passed in VarDecl initializer. + void InitializeVarWithConstructor(VarDecl *VD, + CXXConstructorDecl *Constructor, + QualType DeclInitType, + Expr **Exprs, unsigned NumExprs); + /// InitializationKind - Represents which kind of C++ initialization /// [dcl.init] a routine is to perform. enum InitializationKind { diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 94b3b76a3b..a2b565beb6 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2552,7 +2552,9 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) { if (const ArrayType *Array = Context.getAsArrayType(Type)) InitType = Array->getElementType(); if (!Var->hasExternalStorage() && InitType->isRecordType()) { - const CXXConstructorDecl *Constructor = 0; + CXXRecordDecl *RD = + cast(InitType->getAsRecordType()->getDecl()); + CXXConstructorDecl *Constructor = 0; if (!RequireCompleteType(Var->getLocation(), InitType, diag::err_invalid_incomplete_type_use)) Constructor @@ -2564,6 +2566,8 @@ void Sema::ActOnUninitializedDecl(DeclPtrTy dcl) { IK_Default); if (!Constructor) Var->setInvalidDecl(); + else if (!RD->hasTrivialConstructor()) + InitializeVarWithConstructor(Var, Constructor, InitType, 0, 0); } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 8e2302ed64..e3195a9b28 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1764,6 +1764,18 @@ Sema::DeclPtrTy Sema::ActOnNamespaceAliasDef(Scope *S, return DeclPtrTy::make(AliasDecl); } +void Sema::InitializeVarWithConstructor(VarDecl *VD, + CXXConstructorDecl *Constructor, + QualType DeclInitType, + Expr **Exprs, unsigned NumExprs) { + Expr *Temp = + new (Context) CXXTemporaryObjectExpr(Constructor, DeclInitType, + SourceLocation(), + Exprs, NumExprs, + SourceLocation()); + VD->setInit(Temp); +} + /// AddCXXDirectInitializerToDecl - This action is called immediately after /// ActOnDeclarator, when a C++ direct initializer is present. /// e.g: "int x(1);" @@ -1827,17 +1839,9 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, if (!Constructor) RealDecl->setInvalidDecl(); else { - // Let clients know that initialization was done with a direct - // initializer. VDecl->setCXXDirectInitializer(true); - - Expr *Temp = - new (Context) CXXTemporaryObjectExpr(Constructor, DeclInitType, - SourceLocation(), - (Expr**)Exprs.release(), - NumExprs, - SourceLocation()); - VDecl->setInit(Temp); + InitializeVarWithConstructor(VDecl, Constructor, DeclInitType, + (Expr**)Exprs.release(), NumExprs); } return; }