[cfe-commits] RFC: C++ References Patch
Bill Wendling
isanbard at gmail.com
Tue Nov 27 02:12:51 PST 2007
Hi all,
This is a long awaited patch for the failure in cxx-references.cpp.
The idea is that during the typesAreCompatible method, it should
ignore any references, according to the section [expr] in the C++
standard (quoted in the comment below). At this point, we basically
have a "pointer to a reference" coming into this method. This is
because of how the code is parsed -- the variable is a reference, and
its address is taken. Note, however, that a pointer to a reference is
invalid C++ code. I suppose that we'd ideally like to have it never
be a pointer to a reference. That is to have the reference part of
the type removed before the pointer type to that type is created. I'm
not sure how much information this would lose doing that though.
Because it removes the reference, there's no longer a need to have
the Type::Reference in the switch statement.
Comments?
-bw
Index: test/Sema/cxx-references.cpp
===================================================================
--- test/Sema/cxx-references.cpp (revision 44358)
+++ test/Sema/cxx-references.cpp (working copy)
@@ -5,9 +5,7 @@
int i;
int &r = i;
r = 1;
-#if 0 // FIXME: &ref not right yet
int *p = &r;
-#endif
int &rr = r;
int (&rg)(int) = g;
rg(i);
Index: AST/ASTContext.cpp
===================================================================
--- AST/ASTContext.cpp (revision 44358)
+++ AST/ASTContext.cpp (working copy)
@@ -1217,7 +1217,7 @@
return typesAreCompatible(ltype, rtype);
}
-// C++ 5.17p6: When the left opperand of an assignment operator
denotes a
+// C++ 5.17p6: When the left operand of an assignment operator
denotes a
// reference to T, the operation assigns to the object of type T
denoted by the
// reference.
bool ASTContext::referenceTypesAreCompatible(QualType lhs, QualType
rhs) {
@@ -1299,6 +1299,15 @@
// If two types are identical, they are are compatible
if (lcanon == rcanon)
return true;
+
+ // C++ [expr]: If an expression initially has the type "reference
to T", the
+ // type is adjusted to "T" prior to any further analysis, the
expression
+ // designates the object or function denoted by the reference, and
the
+ // expression is an lvalue.
+ if (lcanon->getTypeClass() == Type::Reference)
+ lcanon = cast<ReferenceType>(lcanon)->getReferenceeType();
+ if (rcanon->getTypeClass() == Type::Reference)
+ rcanon = cast<ReferenceType>(rcanon)->getReferenceeType();
// If the canonical type classes don't match, they can't be
compatible
if (lcanon->getTypeClass() != rcanon->getTypeClass()) {
@@ -1312,8 +1321,6 @@
switch (lcanon->getTypeClass()) {
case Type::Pointer:
return pointerTypesAreCompatible(lcanon, rcanon);
- case Type::Reference:
- return referenceTypesAreCompatible(lcanon, rcanon);
case Type::ConstantArray:
case Type::VariableArray:
return arrayTypesAreCompatible(lcanon, rcanon);
More information about the cfe-commits
mailing list