]> granicus.if.org Git - clang/commitdiff
Fix for testcase that assigns a dereferenced reference to a pointer. The
authorBill Wendling <isanbard@gmail.com>
Mon, 3 Dec 2007 07:33:35 +0000 (07:33 +0000)
committerBill Wendling <isanbard@gmail.com>
Mon, 3 Dec 2007 07:33:35 +0000 (07:33 +0000)
standard says that we should adjust the "reference to T" type to "T"
before analysis.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44530 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
test/Sema/cxx-references.cpp

index 899dfdecb6aa5817da2e8f40621aa7ef8b88f25d..3f5a7fbc586b3973da3ac9c3d8dee0914a0ed07e 100644 (file)
@@ -1217,7 +1217,7 @@ bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
   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 @@ bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
   // 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 @@ bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) {
   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);
index a1c3eb5518de8a83b72ac11da8c67fb0ee41caab..3637573b445e171c83a06f7cd89cdbc32bd8b568 100644 (file)
@@ -5,9 +5,7 @@ void f() {
   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);