2011-10-14 06:29:44 +08:00
|
|
|
// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s
|
2009-03-17 07:22:08 +08:00
|
|
|
|
|
|
|
typedef int&& irr;
|
|
|
|
typedef irr& ilr_c1; // Collapses to int&
|
|
|
|
typedef int& ilr;
|
|
|
|
typedef ilr&& ilr_c2; // Collapses to int&
|
|
|
|
|
|
|
|
irr ret_irr() {
|
2010-12-01 06:57:32 +08:00
|
|
|
return 0; // expected-warning {{returning reference to local temporary}}
|
2009-03-17 07:22:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
struct not_int {};
|
|
|
|
|
|
|
|
int over(int&);
|
|
|
|
not_int over(int&&);
|
|
|
|
|
2009-03-21 04:21:37 +08:00
|
|
|
int over2(const int&);
|
|
|
|
not_int over2(int&&);
|
|
|
|
|
|
|
|
struct conv_to_not_int_rvalue {
|
|
|
|
operator not_int &&();
|
|
|
|
};
|
|
|
|
|
2010-07-01 02:13:39 +08:00
|
|
|
typedef void (fun_type)();
|
|
|
|
void fun();
|
|
|
|
fun_type &&make_fun();
|
|
|
|
|
2009-03-17 07:22:08 +08:00
|
|
|
void f() {
|
|
|
|
int &&virr1; // expected-error {{declaration of reference variable 'virr1' requires an initializer}}
|
|
|
|
int &&virr2 = 0;
|
2011-01-21 09:04:33 +08:00
|
|
|
int &&virr3 = virr2; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}}
|
2009-03-17 07:22:08 +08:00
|
|
|
int i1 = 0;
|
2011-01-21 09:04:33 +08:00
|
|
|
int &&virr4 = i1; // expected-error {{rvalue reference to type 'int' cannot bind to lvalue of type 'int'}}
|
2009-03-17 07:22:08 +08:00
|
|
|
int &&virr5 = ret_irr();
|
2009-03-23 06:30:06 +08:00
|
|
|
int &&virr6 = static_cast<int&&>(i1);
|
|
|
|
(void)static_cast<not_int&&>(i1); // expected-error {{types are not compatible}}
|
2009-03-17 07:22:08 +08:00
|
|
|
|
|
|
|
int i2 = over(i1);
|
|
|
|
not_int ni1 = over(0);
|
|
|
|
int i3 = over(virr2);
|
|
|
|
not_int ni2 = over(ret_irr());
|
|
|
|
|
2009-03-21 04:21:37 +08:00
|
|
|
int i4 = over2(i1);
|
2009-03-29 23:27:50 +08:00
|
|
|
not_int ni3 = over2(0);
|
2009-03-21 04:21:37 +08:00
|
|
|
|
2009-03-17 07:22:08 +08:00
|
|
|
ilr_c1 vilr1 = i1;
|
|
|
|
ilr_c2 vilr2 = i1;
|
2009-03-21 04:21:37 +08:00
|
|
|
|
|
|
|
conv_to_not_int_rvalue cnir;
|
2011-01-21 08:52:42 +08:00
|
|
|
not_int &&ni4 = cnir;
|
2010-03-10 19:27:22 +08:00
|
|
|
not_int &ni5 = cnir; // expected-error{{non-const lvalue reference to type 'not_int' cannot bind to a value of unrelated type 'conv_to_not_int_rvalue'}}
|
2009-03-29 23:27:50 +08:00
|
|
|
not_int &&ni6 = conv_to_not_int_rvalue();
|
2009-03-23 07:49:27 +08:00
|
|
|
|
2010-07-01 02:13:39 +08:00
|
|
|
fun_type &&fun_ref = fun; // works because functions are special
|
|
|
|
fun_type &&fun_ref2 = make_fun(); // same
|
|
|
|
fun_type &fun_lref = make_fun(); // also special
|
2009-03-23 07:49:27 +08:00
|
|
|
|
|
|
|
try {
|
|
|
|
} catch(int&&) { // expected-error {{cannot catch exceptions by rvalue reference}}
|
|
|
|
}
|
2009-03-17 07:22:08 +08:00
|
|
|
}
|
2009-04-13 01:16:29 +08:00
|
|
|
|
|
|
|
int&& should_warn(int i) {
|
|
|
|
// FIXME: The stack address return test doesn't reason about casts.
|
|
|
|
return static_cast<int&&>(i); // xpected-warning {{returning reference to temporary}}
|
|
|
|
}
|
|
|
|
int&& should_not_warn(int&& i) { // But GCC 4.4 does
|
|
|
|
return static_cast<int&&>(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Test the return dance. This also tests IsReturnCopyElidable.
|
|
|
|
struct MoveOnly {
|
|
|
|
MoveOnly();
|
2010-01-08 12:41:39 +08:00
|
|
|
MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate constructor}} \
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
// expected-note 3{{explicitly marked deleted here}}
|
2010-01-06 17:43:14 +08:00
|
|
|
MoveOnly(MoveOnly&&); // expected-note {{candidate constructor}}
|
|
|
|
MoveOnly(int&&); // expected-note {{candidate constructor}}
|
2009-04-13 01:16:29 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
MoveOnly gmo;
|
|
|
|
MoveOnly returningNonEligible() {
|
|
|
|
int i;
|
|
|
|
static MoveOnly mo;
|
|
|
|
MoveOnly &r = mo;
|
|
|
|
if (0) // Copy from global can't be elided
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
return gmo; // expected-error {{call to deleted constructor}}
|
2009-04-13 01:16:29 +08:00
|
|
|
else if (0) // Copy from local static can't be elided
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
return mo; // expected-error {{call to deleted constructor}}
|
2009-04-13 01:16:29 +08:00
|
|
|
else if (0) // Copy from reference can't be elided
|
Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
llvm-svn: 91669
2009-12-18 13:02:21 +08:00
|
|
|
return r; // expected-error {{call to deleted constructor}}
|
2009-04-13 01:16:29 +08:00
|
|
|
else // Construction from different type can't be elided
|
2015-08-26 06:18:46 +08:00
|
|
|
return i; // expected-error {{no viable conversion from returned value of type 'int' to function return type 'MoveOnly'}}
|
2009-04-13 01:16:29 +08:00
|
|
|
}
|