]> granicus.if.org Git - clang/commitdiff
Use CXXTemporaryObjectExpr for explicitly-constructed temporaries. We
authorDouglas Gregor <dgregor@apple.com>
Tue, 2 Mar 2010 17:18:33 +0000 (17:18 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 2 Mar 2010 17:18:33 +0000 (17:18 +0000)
used to do this, but it got lost when we switched functional-style
cast syntax over to using the new initialization code. Fixes PR6457.

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

lib/Sema/SemaInit.cpp
lib/Sema/TreeTransform.h
test/SemaTemplate/instantiate-init.cpp

index 762f6db0a4c7af2d60e9bf0c0e3f854242ff2975..0f8107ac5e494c33193757525ab90687257f4005 100644 (file)
@@ -3439,10 +3439,25 @@ InitializationSequence::Perform(Sema &S,
         return S.ExprError();
           
       // Build the an expression that constructs a temporary.
-      CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
-                                        Constructor, 
-                                        move_arg(ConstructorArgs),
-                                        ConstructorInitRequiresZeroInit,
+      if (Entity.getKind() == InitializedEntity::EK_Temporary &&
+          (Kind.getKind() == InitializationKind::IK_Direct ||
+           Kind.getKind() == InitializationKind::IK_Value)) {
+        // An explicitly-constructed temporary, e.g., X(1, 2).
+        unsigned NumExprs = ConstructorArgs.size();
+        Expr **Exprs = (Expr **)ConstructorArgs.take();
+        S.MarkDeclarationReferenced(Kind.getLocation(), Constructor);
+        CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context,
+                                                                 Constructor,
+                                                              Entity.getType(),
+                                                            Kind.getLocation(),
+                                                                 Exprs, 
+                                                                 NumExprs,
+                                                Kind.getParenRange().getEnd()));
+      } else
+        CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+                                          Constructor, 
+                                          move_arg(ConstructorArgs),
+                                          ConstructorInitRequiresZeroInit,
                                Entity.getKind() == InitializedEntity::EK_Base);
       if (CurInit.isInvalid())
         return S.ExprError();
index dccea49878732a6f18491fb48fd019519df20ae8..2f3c482321741a74df93558fc5a0097b7efb19c0 100644 (file)
@@ -5051,6 +5051,11 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
   for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
                                          ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg) {
+    if (getDerived().DropCallArgument(*Arg)) {
+      ArgumentChanged = true;
+      break;
+    }
+
     OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
     if (TransArg.isInvalid())
       return SemaRef.ExprError();
@@ -5062,8 +5067,11 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
   if (!getDerived().AlwaysRebuild() &&
       T == E->getType() &&
       Constructor == E->getConstructor() &&
-      !ArgumentChanged)
+      !ArgumentChanged) {
+    // FIXME: Instantiation-specific
+    SemaRef.MarkDeclarationReferenced(E->getTypeBeginLoc(), Constructor);
     return SemaRef.Owned(E->Retain());
+  }
 
   // FIXME: Bogus location information
   SourceLocation CommaLoc;
index 8a10a87e610e930a8e0415cf76bd213f9d8d7a1c..16ecc4758ab53cc789b0aef92665d40163094818 100644 (file)
@@ -26,3 +26,14 @@ void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
   f1(x0, ip, dp); // expected-note{{instantiation}}
 }
 
+namespace PR6457 {
+  template <typename T> struct X { explicit X(T* p = 0) { }; };
+  template <typename T> struct Y { Y(int, const T& x); };
+  struct A { };
+  template <typename T>
+  struct B {
+    B() : y(0, X<A>()) { }
+    Y<X<A> > y;
+  };
+  B<int> b;
+}