summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-12-18 05:02:21 +0000
committerDouglas Gregor <dgregor@apple.com>2009-12-18 05:02:21 +0000
commite1314a64b803bfffe98bd43f9131e512fd7191dd (patch)
treee64925d088af17ee9710a4afc3054b565d130e8c /clang/test
parent7a2dab882669e2b86a110bb38046149f1a5013d8 (diff)
downloadbcm5719-llvm-e1314a64b803bfffe98bd43f9131e512fd7191dd.tar.gz
bcm5719-llvm-e1314a64b803bfffe98bd43f9131e512fd7191dd.zip
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
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp4
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp2
-rw-r--r--clang/test/CodeGenCXX/temporaries.cpp14
-rw-r--r--clang/test/SemaCXX/conversion-function.cpp14
-rw-r--r--clang/test/SemaCXX/decl-init-ref.cpp2
-rw-r--r--clang/test/SemaCXX/ref-init-ambiguous.cpp7
-rw-r--r--clang/test/SemaCXX/rval-references-xfail.cpp14
-rw-r--r--clang/test/SemaCXX/rval-references.cpp14
-rw-r--r--clang/test/SemaTemplate/class-template-id.cpp6
-rw-r--r--clang/test/SemaTemplate/constructor-template.cpp8
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-4.cpp2
-rw-r--r--clang/test/SemaTemplate/instantiate-function-1.cpp2
-rw-r--r--clang/test/SemaTemplate/instantiate-member-template.cpp4
-rw-r--r--clang/test/SemaTemplate/instantiate-typedef.cpp2
14 files changed, 64 insertions, 31 deletions
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
index e55fcc42455..a0904189161 100644
--- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -91,7 +91,7 @@ void bind_lvalue_to_conv_lvalue() {
void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both) {
Derived &dr1 = both;
- Base &br1 = both; // expected-error{{error: conversion from 'struct ConvertibleToBothDerivedRef' to 'struct Base' is ambiguous}}
+ Base &br1 = both; // expected-error{{reference initialization of type 'struct Base &' with initializer of type 'struct ConvertibleToBothDerivedRef' is ambiguous}}
}
struct IntBitfield {
@@ -125,5 +125,5 @@ void bind_const_lvalue_to_class_conv_temporary() {
}
void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
const Derived &dr1 = both;
- const Base &br1 = both; // expected-error{{error: conversion from 'struct ConvertibleToBothDerived' to 'struct Base const' is ambiguous}}
+ const Base &br1 = both; // expected-error{{reference initialization of type 'struct Base const &' with initializer of type 'struct ConvertibleToBothDerived' is ambiguous}}
}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
index 88cca39e282..58479cda263 100644
--- a/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -17,7 +17,7 @@ struct X2 { };
int& get_int() { return X0<int>::value; }
X1& get_X1() { return X0<X1>::value; }
-double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{initialized}}
+double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{non-const lvalue reference to type 'double *' cannot bind to a value of unrelated type 'int *'}}
X2& get_X2() {
return X0<X2>::value; // expected-note{{instantiation}}
diff --git a/clang/test/CodeGenCXX/temporaries.cpp b/clang/test/CodeGenCXX/temporaries.cpp
index f6b183fc84b..f83bbeeac80 100644
--- a/clang/test/CodeGenCXX/temporaries.cpp
+++ b/clang/test/CodeGenCXX/temporaries.cpp
@@ -202,3 +202,17 @@ void f11(H h) {
// CHECK: ret void
f10(h);
}
+
+// PR5808
+struct I {
+ I(const char *);
+ ~I();
+};
+
+// CHECK: _Z3f12v
+I f12() {
+ // CHECK: call void @_ZN1IC1EPKc
+ // CHECK-NOT: call void @_ZN1ID1Ev
+ // CHECK: ret void
+ return "Hello";
+}
diff --git a/clang/test/SemaCXX/conversion-function.cpp b/clang/test/SemaCXX/conversion-function.cpp
index 997e19c3888..fca5a4a72aa 100644
--- a/clang/test/SemaCXX/conversion-function.cpp
+++ b/clang/test/SemaCXX/conversion-function.cpp
@@ -99,7 +99,7 @@ class AutoPtrRef { };
class AutoPtr {
// FIXME: Using 'unavailable' since we do not have access control yet.
// FIXME: The error message isn't so good.
- AutoPtr(AutoPtr &) __attribute__((unavailable));
+ AutoPtr(AutoPtr &) __attribute__((unavailable)); // expected-note{{explicitly marked}}
public:
AutoPtr();
@@ -115,9 +115,19 @@ AutoPtr test_auto_ptr(bool Cond) {
AutoPtr p;
if (Cond)
- return p; // expected-error{{incompatible type returning}}
+ return p; // expected-error{{call to deleted constructor}}
return AutoPtr();
}
+struct A1 {
+ A1(const char *);
+ ~A1();
+private:
+ A1(const A1&) __attribute__((unavailable)); // expected-note{{here}}
+};
+
+A1 f() {
+ return "Hello"; // expected-error{{invokes deleted copy constructor}}
+}
diff --git a/clang/test/SemaCXX/decl-init-ref.cpp b/clang/test/SemaCXX/decl-init-ref.cpp
index 4200b169abe..294543f495d 100644
--- a/clang/test/SemaCXX/decl-init-ref.cpp
+++ b/clang/test/SemaCXX/decl-init-ref.cpp
@@ -21,6 +21,6 @@ extern B f();
const int& ri = (void)0; // expected-error {{reference to type 'int const' could not bind to an rvalue of type 'void'}}
int main() {
- const A& rca = f(); // expected-error {{conversion from 'class B' to 'struct A const' is ambiguous}}
+ const A& rca = f(); // expected-error {{reference initialization of type 'struct A const &' with initializer of type 'class B' is ambiguous}}
A& ra = f(); // expected-error {{non-const lvalue reference to type 'struct A' cannot bind to a temporary of type 'class B'}}
}
diff --git a/clang/test/SemaCXX/ref-init-ambiguous.cpp b/clang/test/SemaCXX/ref-init-ambiguous.cpp
index c17d613cae9..976879ecd0a 100644
--- a/clang/test/SemaCXX/ref-init-ambiguous.cpp
+++ b/clang/test/SemaCXX/ref-init-ambiguous.cpp
@@ -3,19 +3,18 @@
enum E2 { };
struct A {
- operator E2&(); // expected-note 2 {{candidate function}}
+ operator E2&(); // expected-note 3 {{candidate function}}
};
struct B {
- operator E2&(); // expected-note 2 {{candidate function}}
+ operator E2&(); // expected-note 3 {{candidate function}}
};
struct C : B, A {
};
void test(C c) {
- // FIXME: state that there was an ambiguity in the conversion!
- const E2 &e2 = c; // expected-error {{reference to type 'enum E2 const' could not bind to an lvalue of type 'struct C'}}
+ const E2 &e2 = c; // expected-error {{reference initialization of type 'enum E2 const &' with initializer of type 'struct C' is ambiguous}}
}
void foo(const E2 &);
diff --git a/clang/test/SemaCXX/rval-references-xfail.cpp b/clang/test/SemaCXX/rval-references-xfail.cpp
new file mode 100644
index 00000000000..d41f8f141cd
--- /dev/null
+++ b/clang/test/SemaCXX/rval-references-xfail.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+// XFAIL: *
+struct MoveOnly {
+ MoveOnly();
+ MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}} \
+ // expected-note 3{{explicitly marked deleted here}}
+ MoveOnly(MoveOnly&&); // expected-note {{candidate function}}
+ MoveOnly(int&&); // expected-note {{candidate function}}
+};
+
+MoveOnly returning() {
+ MoveOnly mo;
+ return mo;
+}
diff --git a/clang/test/SemaCXX/rval-references.cpp b/clang/test/SemaCXX/rval-references.cpp
index 17e7584a604..7ff3d584c02 100644
--- a/clang/test/SemaCXX/rval-references.cpp
+++ b/clang/test/SemaCXX/rval-references.cpp
@@ -65,27 +65,23 @@ int&& should_not_warn(int&& i) { // But GCC 4.4 does
// Test the return dance. This also tests IsReturnCopyElidable.
struct MoveOnly {
MoveOnly();
- MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}}
+ MoveOnly(const MoveOnly&) = delete; // expected-note {{candidate function}} \
+ // expected-note 3{{explicitly marked deleted here}}
MoveOnly(MoveOnly&&); // expected-note {{candidate function}}
MoveOnly(int&&); // expected-note {{candidate function}}
};
-MoveOnly returning() {
- MoveOnly mo;
- return mo;
-}
-
MoveOnly gmo;
MoveOnly returningNonEligible() {
int i;
static MoveOnly mo;
MoveOnly &r = mo;
if (0) // Copy from global can't be elided
- return gmo; // expected-error {{incompatible type returning}}
+ return gmo; // expected-error {{call to deleted constructor}}
else if (0) // Copy from local static can't be elided
- return mo; // expected-error {{incompatible type returning}}
+ return mo; // expected-error {{call to deleted constructor}}
else if (0) // Copy from reference can't be elided
- return r; // expected-error {{incompatible type returning}}
+ return r; // expected-error {{call to deleted constructor}}
else // Construction from different type can't be elided
return i; // expected-error {{no viable conversion from 'int' to 'struct MoveOnly'}}
}
diff --git a/clang/test/SemaTemplate/class-template-id.cpp b/clang/test/SemaTemplate/class-template-id.cpp
index bb9d39d82af..df5ef554f7a 100644
--- a/clang/test/SemaTemplate/class-template-id.cpp
+++ b/clang/test/SemaTemplate/class-template-id.cpp
@@ -9,9 +9,9 @@ A<int, FLOAT> *foo(A<int> *ptr, A<int> const *ptr2, A<int, double> *ptr3) {
if (ptr)
return ptr; // okay
else if (ptr2)
- return ptr2; // expected-error{{incompatible type returning 'A<int> const *', expected 'A<int, FLOAT> *'}}
+ return ptr2; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'A<int> const *'}}
else {
- return ptr3; // expected-error{{incompatible type returning 'A<int, double> *', expected 'A<int, FLOAT> *'}}
+ return ptr3; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'A<int, double> *'}}
}
}
@@ -24,7 +24,7 @@ B<17 + 2> *bar(B<(19)> *ptr1, B< (::value + 7) > *ptr2, B<19 - 3> *ptr3) {
else if (ptr2)
return ptr2;
else
- return ptr3; // expected-error{{incompatible type returning 'B<19 - 3> *', expected 'B<17 + 2> *'}}
+ return ptr3; // expected-error{{cannot initialize return object of type 'B<17 + 2> *' with an lvalue of type 'B<19 - 3>}}
}
typedef B<5> B5;
diff --git a/clang/test/SemaTemplate/constructor-template.cpp b/clang/test/SemaTemplate/constructor-template.cpp
index 68aaa646fba..139de9d6860 100644
--- a/clang/test/SemaTemplate/constructor-template.cpp
+++ b/clang/test/SemaTemplate/constructor-template.cpp
@@ -52,7 +52,7 @@ template <> struct A<int>{A(const A<int>&);};
struct B { A<int> x; B(B& a) : x(a.x) {} };
struct X2 {
- X2();
+ X2(); // expected-note{{candidate function}}
X2(X2&); // expected-note {{candidate function}}
template<typename T> X2(T);
};
@@ -61,7 +61,7 @@ X2 test(bool Cond, X2 x2) {
if (Cond)
return x2; // okay, uses copy constructor
- return X2(); // expected-error{{no viable conversion from 'struct X2' to 'struct X2' is possible}}
+ return X2(); // expected-error{{no matching constructor}}
}
struct X3 {
@@ -71,7 +71,7 @@ struct X3 {
template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}}
struct X4 {
- X4();
+ X4(); // expected-note{{candidate function}}
~X4();
X4(X4&); // expected-note {{candidate function}}
template<typename T> X4(const T&, int = 17);
@@ -80,7 +80,7 @@ struct X4 {
X4 test_X4(bool Cond, X4 x4) {
X4 a(x4, 17); // okay, constructor template
X4 b(x4); // okay, copy constructor
- return X4(); // expected-error{{no viable conversion}}
+ return X4(); // expected-error{{no matching constructor}}
}
// Instantiation of a non-dependent use of a constructor
diff --git a/clang/test/SemaTemplate/instantiate-expr-4.cpp b/clang/test/SemaTemplate/instantiate-expr-4.cpp
index ffe1d58f28c..e0042de50e6 100644
--- a/clang/test/SemaTemplate/instantiate-expr-4.cpp
+++ b/clang/test/SemaTemplate/instantiate-expr-4.cpp
@@ -293,7 +293,7 @@ template struct NonDepMemberCall0<float&>; // expected-note{{instantiation}}
template<typename T>
struct QualifiedDeclRef0 {
T f() {
- return is_pod<X>::value; // expected-error{{initialized}}
+ return is_pod<X>::value; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'bool const'}}
}
};
diff --git a/clang/test/SemaTemplate/instantiate-function-1.cpp b/clang/test/SemaTemplate/instantiate-function-1.cpp
index 52707ca63e4..543b3cc1975 100644
--- a/clang/test/SemaTemplate/instantiate-function-1.cpp
+++ b/clang/test/SemaTemplate/instantiate-function-1.cpp
@@ -66,7 +66,7 @@ template<typename T, typename U, typename V> struct X6 {
return u;
else {
if (t < 0)
- return v; // expected-error{{incompatible type}}
+ return v; // expected-error{{cannot initialize return object of type}}
}
if (T x = t) {
diff --git a/clang/test/SemaTemplate/instantiate-member-template.cpp b/clang/test/SemaTemplate/instantiate-member-template.cpp
index 6442ed417c5..2b5ba5c891e 100644
--- a/clang/test/SemaTemplate/instantiate-member-template.cpp
+++ b/clang/test/SemaTemplate/instantiate-member-template.cpp
@@ -50,7 +50,7 @@ struct X1 {
template<typename V>
V f1(T t, U u, V) {
- return t + u; // expected-error{{incompatible type}}
+ return t + u; // expected-error{{cannot initialize return object}}
}
};
@@ -75,7 +75,7 @@ template<typename T>
template<typename U>
template<typename V>
V X1<T>::Inner4<U>::f2(T t, U u, V) {
- return t + u; // expected-error{{incompatible type}}
+ return t + u; // expected-error{{cannot initialize return object}}
}
void test_X1(int *ip, int i, double *dp) {
diff --git a/clang/test/SemaTemplate/instantiate-typedef.cpp b/clang/test/SemaTemplate/instantiate-typedef.cpp
index be769c00eca..977fd08cc36 100644
--- a/clang/test/SemaTemplate/instantiate-typedef.cpp
+++ b/clang/test/SemaTemplate/instantiate-typedef.cpp
@@ -8,7 +8,7 @@ struct add_pointer {
add_pointer<int>::type test1(int * ptr) { return ptr; }
add_pointer<float>::type test2(int * ptr) {
- return ptr; // expected-error{{incompatible type returning 'int *', expected 'add_pointer<float>::type' (aka 'float *')}}
+ return ptr; // expected-error{{cannot initialize return object of type 'add_pointer<float>::type' (aka 'float *') with an lvalue of type 'int *'}}
}
add_pointer<int&>::type // expected-note{{in instantiation of template class 'struct add_pointer<int &>' requested here}} \
OpenPOWER on IntegriCloud