[cfe-commits] r123918 - in /cfe/trunk: lib/Sema/SemaInit.cpp test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
Douglas Gregor
dgregor at apple.com
Thu Jan 20 08:44:54 PST 2011
Author: dgregor
Date: Thu Jan 20 10:44:54 2011
New Revision: 123918
URL: http://llvm.org/viewvc/llvm-project?rev=123918&view=rev
Log:
Start refactoring reference binding to more closely match the C++0x
working paper's structure. The only functional change here is that we
now handling binding to array rvalues, which we would previously reject.
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=123918&r1=123917&r2=123918&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Jan 20 10:44:54 2011
@@ -2597,13 +2597,17 @@
return;
}
- // - [If T1 is not a function type], if T2 is a class type and
- if (!T1Function && T2->isRecordType()) {
- bool isXValue = InitCategory.isXValue();
- // - the initializer expression is an rvalue and "cv1 T1" is
- // reference-compatible with "cv2 T2", or
- if (InitCategory.isRValue() &&
- RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) {
+ // - If the initializer expression
+ // - is an xvalue, class prvalue, array prvalue, or function lvalue and
+ // "cv1 T1" is reference-compatible with "cv2 T2"
+ // Note: functions are handled below.
+ if (!T1Function &&
+ RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification &&
+ (InitCategory.isXValue() ||
+ (InitCategory.isPRValue() && T2->isRecordType()) ||
+ (InitCategory.isPRValue() && T2->isArrayType()))) {
+ ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue;
+ if (InitCategory.isPRValue() && T2->isRecordType()) {
// The corresponding bullet in C++03 [dcl.init.ref]p5 gives the
// compiler the freedom to perform a copy here or bind to the
// object, while C++0x requires that we bind directly to the
@@ -2615,27 +2619,30 @@
// be callable whether or not the copy is actually done.
if (!S.getLangOptions().CPlusPlus0x && !S.getLangOptions().Microsoft)
Sequence.AddExtraneousCopyToTemporary(cv2T2);
-
- if (DerivedToBase)
- Sequence.AddDerivedToBaseCastStep(
- S.Context.getQualifiedType(T1, T2Quals),
- isXValue ? VK_XValue : VK_RValue);
- else if (ObjCConversion)
- Sequence.AddObjCObjectConversionStep(
- S.Context.getQualifiedType(T1, T2Quals));
-
- if (T1Quals != T2Quals)
- Sequence.AddQualificationConversionStep(cv1T1,
- isXValue ? VK_XValue : VK_RValue);
- Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue);
- return;
}
-
- // - T1 is not reference-related to T2 and the initializer expression
- // can be implicitly converted to an rvalue of type "cv3 T3" (this
- // conversion is selected by enumerating the applicable conversion
- // functions (13.3.1.6) and choosing the best one through overload
- // resolution (13.3)),
+
+ if (DerivedToBase)
+ Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals),
+ ValueKind);
+ else if (ObjCConversion)
+ Sequence.AddObjCObjectConversionStep(
+ S.Context.getQualifiedType(T1, T2Quals));
+
+ if (T1Quals != T2Quals)
+ Sequence.AddQualificationConversionStep(cv1T1, ValueKind);
+ Sequence.AddReferenceBindingStep(cv1T1,
+ /*bindingTemporary=*/(InitCategory.isPRValue() && !T2->isArrayType()));
+ return;
+ }
+
+ // - has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to an
+ // xvalue, class prvalue, or function lvalue of type "cv3 T3",
+ // where "cv1 T1" is reference-compatible with "cv3 T3",
+ //
+ // FIXME: Need to handle xvalue, class prvalue, etc. cases in
+ // TryRefInitWithConversionFunction.
+ if (T2->isRecordType()) {
if (RefRelationship == Sema::Ref_Incompatible) {
ConvOvlResult = TryRefInitWithConversionFunction(S, Entity,
Kind, Initializer,
@@ -2652,13 +2659,7 @@
Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers);
return;
}
-
- // - If the initializer expression is an rvalue, with T2 an array type,
- // and "cv1 T1" is reference-compatible with "cv2 T2," the reference
- // is bound to the object represented by the rvalue (see 3.10).
- // FIXME: How can an array type be reference-compatible with anything?
- // Don't we mean the element types of T1 and T2?
-
+
// - Otherwise, a temporary of type âcv1 T1â is created and initialized
// from the initializer expression using the rules for a non-reference
// copy initialization (8.5). The reference is then bound to the
Modified: cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp?rev=123918&r1=123917&r2=123918&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp Thu Jan 20 10:44:54 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify -pedantic %s
// Test the C++0x-specific reference initialization rules, e.g., the
// rules for rvalue references.
@@ -30,9 +30,28 @@
Base&& base2 = prvalue<Base>();
Base&& base3 = prvalue<Derived>();
- // FIXME: array prvalue case
- // int (&&array0)[5] = HasArray().array;
+ // array prvalue case
+ int (&&array0)[5] = HasArray().array;
// function lvalue case
int (&&function0)(int) = f;
}
+
+class NonCopyable {
+ NonCopyable(const NonCopyable&);
+};
+
+class NonCopyableDerived : public NonCopyable {
+ NonCopyableDerived(const NonCopyableDerived&);
+};
+
+void test_direct_binding() {
+ NonCopyable &&nc0 = prvalue<NonCopyable>();
+ NonCopyable &&nc1 = prvalue<NonCopyableDerived>();
+ NonCopyable &&nc2 = xvalue<NonCopyable>();
+ NonCopyable &&nc3 = xvalue<NonCopyableDerived>();
+ const NonCopyable &nc4 = prvalue<NonCopyable>();
+ const NonCopyable &nc5 = prvalue<NonCopyableDerived>();
+ const NonCopyable &nc6 = xvalue<NonCopyable>();
+ const NonCopyable &nc7 = xvalue<NonCopyableDerived>();
+}
More information about the cfe-commits
mailing list