[cfe-commits] r80206 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/default-argument-temporaries.cpp

Anders Carlsson andersca at mac.com
Wed Aug 26 22:08:22 PDT 2009


Author: andersca
Date: Thu Aug 27 00:08:22 2009
New Revision: 80206

URL: http://llvm.org/viewvc/llvm-project?rev=80206&view=rev
Log:
Add a BuildCXXTemporaryObjectExpr and use it so default arguments will be instantiated correctly for temporary object expressions.

Added:
    cfe/trunk/test/SemaCXX/default-argument-temporaries.cpp
Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=80206&r1=80205&r2=80206&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Aug 27 00:08:22 2009
@@ -1774,6 +1774,12 @@
                                          bool Elidable,
                                          Expr **Exprs, unsigned NumExprs);
   
+  OwningExprResult BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Cons, 
+                                               QualType writtenTy, 
+                                               SourceLocation tyBeginLoc, 
+                                               MultiExprArg Args,
+                                               SourceLocation rParenLoc);
+                                               
   /// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
   /// the default expr if needed.
   OwningExprResult BuildCXXDefaultArgExpr(SourceLocation CallLoc,

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=80206&r1=80205&r2=80206&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug 27 00:08:22 2009
@@ -2467,7 +2467,7 @@
                                                                 Elidable,
                                                                 Exprs,
                                                                 NumExprs));
-  // default arguments must be added to constructor call expression.
+  // Default arguments must be added to constructor call expression.
   FunctionDecl *FDecl = cast<FunctionDecl>(Constructor);
   unsigned NumArgsInProto = FDecl->param_size();
   for (unsigned j = NumExprs; j != NumArgsInProto; j++) {
@@ -2484,6 +2484,37 @@
   return move(Temp);
 }
 
+Sema::OwningExprResult
+Sema::BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Constructor, 
+                                  QualType Ty, 
+                                  SourceLocation TyBeginLoc, 
+                                  MultiExprArg Args,
+                                  SourceLocation RParenLoc) {
+  CXXTemporaryObjectExpr *E 
+    = new (Context) CXXTemporaryObjectExpr(Context, Constructor, Ty, TyBeginLoc, 
+                                           (Expr **)Args.get(),
+                                           Args.size(), RParenLoc);
+  
+  ExprOwningPtr<CXXTemporaryObjectExpr> Temp(this, E);
+
+    // Default arguments must be added to constructor call expression.
+  FunctionDecl *FDecl = cast<FunctionDecl>(Constructor);
+  unsigned NumArgsInProto = FDecl->param_size();
+  for (unsigned j = Args.size(); j != NumArgsInProto; j++) {
+    ParmVarDecl *Param = FDecl->getParamDecl(j);
+
+    OwningExprResult ArgExpr = BuildCXXDefaultArgExpr(TyBeginLoc, FDecl, Param);
+    if (ArgExpr.isInvalid())
+      return ExprError();
+
+    Temp->setArg(j, ArgExpr.takeAs<Expr>());
+  }
+
+  Args.release();
+  return move(Temp);
+}
+
+
 bool Sema::InitializeVarWithConstructor(VarDecl *VD, 
                                         CXXConstructorDecl *Constructor,
                                         QualType DeclInitType, 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=80206&r1=80205&r2=80206&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Aug 27 00:08:22 2009
@@ -239,9 +239,8 @@
   if (const RecordType *RT = Ty->getAs<RecordType>()) {
     CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
 
-    // FIXME: We should always create a CXXTemporaryObjectExpr here unless
-    // both the ctor and dtor are trivial.
-    if (NumExprs > 1 || Record->hasUserDeclaredConstructor()) {
+    if (NumExprs > 1 || !Record->hasTrivialConstructor() || 
+        !Record->hasTrivialDestructor()) {
       CXXConstructorDecl *Constructor
         = PerformInitializationByConstructor(Ty, Exprs, NumExprs,
                                              TypeRange.getBegin(),
@@ -253,11 +252,13 @@
       if (!Constructor)
         return ExprError();
 
-      exprs.release();
-      Expr *E = new (Context) CXXTemporaryObjectExpr(Context, Constructor, 
-                                                     Ty, TyBeginLoc, Exprs,
-                                                     NumExprs, RParenLoc);
-      return MaybeBindToTemporary(E);
+      OwningExprResult Result = 
+        BuildCXXTemporaryObjectExpr(Constructor, Ty, TyBeginLoc, 
+                                    move(exprs), RParenLoc);
+      if (Result.isInvalid())
+        return ExprError();
+      
+      return MaybeBindToTemporary(Result.takeAs<Expr>());
     }
 
     // Fall through to value-initialize an object of class type that

Added: cfe/trunk/test/SemaCXX/default-argument-temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default-argument-temporaries.cpp?rev=80206&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/default-argument-temporaries.cpp (added)
+++ cfe/trunk/test/SemaCXX/default-argument-temporaries.cpp Thu Aug 27 00:08:22 2009
@@ -0,0 +1,11 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+struct B { B(void* = 0); };
+
+struct A {
+  A(B b = B()) { }
+};
+
+void f() {
+  (void)B();
+  (void)A();
+}





More information about the cfe-commits mailing list