]> granicus.if.org Git - clang/commitdiff
DR1048: drop top-level cv-qualifiers when deducing the return type of a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 19 Dec 2014 22:10:51 +0000 (22:10 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Fri, 19 Dec 2014 22:10:51 +0000 (22:10 +0000)
lambda-expression in C++11, to match the C++14 rules.

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

lib/Sema/SemaLambda.cpp
lib/Sema/SemaStmt.cpp
test/CXX/drs/dr10xx.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/p4.cpp
test/SemaCXX/lambda-expressions.cpp
www/cxx_dr_status.html

index a64a0fb323dabff68efa4f3062e2366a6d345768..90a81f4ec452795eb919a7568b3edd8c4903bab6 100644 (file)
@@ -617,7 +617,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
   // If it was ever a placeholder, it had to been deduced to DependentTy.
   assert(CSI.ReturnType.isNull() || !CSI.ReturnType->isUndeducedType()); 
 
-  // C++ Core Issue #975, proposed resolution:
+  // C++ core issue 975:
   //   If a lambda-expression does not include a trailing-return-type,
   //   it is as if the trailing-return-type denotes the following type:
   //     - if there are no return statements in the compound-statement,
@@ -631,6 +631,10 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
   //       same, that common type;
   //     - otherwise, the program is ill-formed.
   //
+  // C++ core issue 1048 additionally removes top-level cv-qualifiers
+  // from the types of returned expressions to match the C++14 auto
+  // deduction rules.
+  //
   // In addition, in blocks in non-C++ modes, if all of the return
   // statements are enumerator-like expressions of some type T, where
   // T has a name for linkage, then we infer the return type of the
@@ -679,7 +683,8 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
     const ReturnStmt *RS = *I;
     const Expr *RetE = RS->getRetValue();
 
-    QualType ReturnType = (RetE ? RetE->getType() : Context.VoidTy);
+    QualType ReturnType =
+        (RetE ? RetE->getType() : Context.VoidTy).getUnqualifiedType();
     if (Context.hasSameType(ReturnType, CSI.ReturnType))
       continue;
 
index a3fd6fa9a176471cc02b096e5e28032015e17ce8..f487752070664e526d4e143c5a24b9429624f7b0 100644 (file)
@@ -2652,8 +2652,12 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
         return StmtError();
       RetValExp = Result.get();
 
+      // DR1048: even prior to C++14, we should use the 'auto' deduction rules
+      // when deducing a return type for a lambda-expression (or by extension
+      // for a block). These rules differ from the stated C++11 rules only in
+      // that they remove top-level cv-qualifiers.
       if (!CurContext->isDependentContext())
-        FnRetType = RetValExp->getType();
+        FnRetType = RetValExp->getType().getUnqualifiedType();
       else
         FnRetType = CurCap->ReturnType = Context.DependentTy;
     } else {
index 733621d2124ba756e9ccb43b8353066b494766f9..a1d7ef67c66d9bcf85ddf3b6a10d55a52781ad96 100644 (file)
@@ -14,6 +14,24 @@ namespace std {
   };
 }
 
+namespace dr1048 { // dr1048: 3.6
+  struct A {};
+  const A f();
+  A g();
+  typedef const A CA;
+#if __cplusplus >= 201103L
+  // ok: we deduce non-const A in each case.
+  A &&a = [] (int n) {
+    while (1) switch (n) {
+      case 0: return f();
+      case 1: return g();
+      case 2: return A();
+      case 3: return CA();
+    }
+  } (0);
+#endif
+}
+
 namespace dr1070 { // dr1070: 3.5
 #if __cplusplus >= 201103L
   struct A {
index 1016cb1d3056c8c2337d24d177606f18414368be..a36175af6fec539d081a98bf783cf65953e15adb 100644 (file)
@@ -34,15 +34,12 @@ X infer_X_return_type(X x) {
   }(5);
 }
 
-X infer_X_return_type_fail(X x) {
+X infer_X_return_type_2(X x) {
   return [x](int y) {
     if (y > 0)
       return X();
     else
-      return x;
-#if __cplusplus <= 201103L
-    // expected-error@-2 {{return type 'const X' must match previous return type 'X' when lambda expression has unspecified explicit return type}}
-#endif
+      return x; // ok even in c++11, per dr1048.
   }(5);
 }
 
index 62208959ae10e153b2be7d04813be6c98892a121..cad322ab52fe34ba702153800cc5c6f346fba0e7 100644 (file)
@@ -258,9 +258,7 @@ namespace TypeDeduction {
   void f() {
     const S s {};
     S &&t = [&] { return s; } ();
-#if __cplusplus <= 201103L
-    // expected-error@-2 {{drops qualifiers}}
-#else
+#if __cplusplus > 201103L
     S &&u = [&] () -> auto { return s; } ();
 #endif
   }
index 4645e520424db2e2870b403fcc95b38e07a4bd23..d8dc9bcbc02035b120d36d2d768c141c247dc05c 100644 (file)
@@ -6103,7 +6103,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1048">1048</a></td>
     <td>CD3</td>
     <td><TT>auto</TT> deduction and lambda return type deduction.</td>
-    <td class="none" align="center">Unknown</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="1049">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1049">1049</a></td>