[cfe-commits] r101705 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp

Douglas Gregor dgregor at apple.com
Sun Apr 18 00:57:34 PDT 2010


Author: dgregor
Date: Sun Apr 18 02:57:34 2010
New Revision: 101705

URL: http://llvm.org/viewvc/llvm-project?rev=101705&view=rev
Log:
When checking the copy constructor for the optional copy during a
reference binding to an rvalue of reference-compatible type, check
parameters after the first for complete parameter types and build any
required default function arguments. We're effectively simulating the
type-checking for a call without building the call itself.


Modified:
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp
    cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=101705&r1=101704&r2=101705&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sun Apr 18 02:57:34 2010
@@ -3264,10 +3264,26 @@
   if (IsExtraneousCopy) {
     // If this is a totally extraneous copy for C++03 reference
     // binding purposes, just return the original initialization
-    // expression.
+    // expression. We don't generate an (elided) copy operation here
+    // because doing so would require us to pass down a flag to avoid
+    // infinite recursion, where each step adds another extraneous,
+    // elidable copy.
+
+    // Instantiate the default arguments of any extra parameters in
+    // the selected copy constructor, as if we were going to create a
+    // proper call to the copy constructor.
+    for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {
+      ParmVarDecl *Parm = Constructor->getParamDecl(I);
+      if (S.RequireCompleteType(Loc, Parm->getType(),
+                                S.PDiag(diag::err_call_incomplete_argument)))
+        break;
+
+      // Build the default argument expression; we don't actually care
+      // if this succeeds or not, because this routine will complain
+      // if there was a problem.
+      S.BuildCXXDefaultArgExpr(Loc, Constructor, Parm);
+    }
 
-    // FIXME: We'd like to call CompleteConstructorCall below, so that
-    // we instantiate default arguments and such.
     return S.Owned(CurInitExpr);
   }
   

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp?rev=101705&r1=101704&r2=101705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p16-cxx0x-no-extra-copy.cpp Sun Apr 18 02:57:34 2010
@@ -27,8 +27,7 @@
 template<typename T>
 T get_value_badly() {
   double *dp = 0;
-  T *tp = dp; // FIXME: Should get an error here, from instantiating the
-              // default argument of X4<int>
+  T *tp = dp;
   return T();
 }
 

Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp?rev=101705&r1=101704&r2=101705&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp Sun Apr 18 02:57:34 2010
@@ -24,28 +24,38 @@
   X3(X3&); // expected-note{{candidate constructor not viable: no known conversion from 'X3' to 'X3 &' for 1st argument}}
 };
 
+// Check for instantiation of default arguments
 template<typename T>
 T get_value_badly() {
   double *dp = 0;
-  T *tp = dp; // FIXME: Should get an error here, from instantiating the
-              // default argument of X4<int>
+  T *tp = dp; // expected-error{{ cannot initialize a variable of type 'int *' with an lvalue of type 'double *'}}
   return T();
 }
 
 template<typename T>
 struct X4 {
   X4();
-  X4(const X4&, T = get_value_badly<T>());
+  X4(const X4&, T = get_value_badly<T>()); // expected-note{{in instantiation of}}
+}; 
+
+// Check for "dangerous" default arguments that could cause recursion.
+struct X5 {
+  X5();
+  X5(const X5&, const X5& = X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}}
 };
 
 void g1(const X1&);
 void g2(const X2&);
 void g3(const X3&);
 void g4(const X4<int>&);
+void g5(const X5&);
 
 void test() {
   g1(X1()); // expected-error{{no viable constructor copying parameter of type 'X1'}}
   g2(X2()); // expected-error{{calling a private constructor of class 'X2'}}
   g3(X3()); // expected-error{{no viable constructor copying parameter of type 'X3'}}
   g4(X4<int>());
+  g5(X5()); // expected-error{{no viable constructor copying parameter of type 'X5'}}
 }
+
+// Check for dangerous recursion in default arguments.





More information about the cfe-commits mailing list