// 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,
// 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
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;
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 {
};
}
+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 {
}(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);
}
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
}
<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>