[cfe-commits] r39439 - in /cfe/cfe/trunk: AST/Sema.h AST/SemaExpr.cpp AST/Type.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def

Steve Naroff snaroff at apple.com
Wed Jul 11 09:44:25 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:44:24 2007
New Revision: 39439

URL: http://llvm.org/viewvc/llvm-project?rev=39439&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Enhanced UsualAssignmentConversions() to properly handle type qualifiers on
pointers.
- Added helper function Sema::pointerTypeQualifiersAlign().
- Noticed several errors improperly named "ext_" (fixed).
- Combined structureTypesAreCompatible/unionTypesAreCompatible into
tagTypesAreCompatible.
- Renamed Type::getCanonicalType() to Type::getCanonicalTypeInternal(). It
will never confuse/bite me again:-)
- Added a couple extension diagnostics for discarded type qualifiers.

Modified:
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaExpr.cpp
    cfe/cfe/trunk/AST/Type.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaExpr.cpp
    cfe/cfe/trunk/include/clang/AST/Type.h
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:44:24 2007
@@ -236,13 +236,16 @@
     Incompatible,
     PointerFromInt, 
     IntFromPointer,
-    IncompatiblePointer
+    IncompatiblePointer,
+    CompatiblePointerDiscardsQualifiers
   };
   // Conversions for assignment, argument passing, initialization, and
   // function return values. UsualAssignmentConversions is currently used by 
   // CheckSimpleAssignment, CheckCompoundAssignment and ParseCallExpr. 
   QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
-                                      AssignmentConversionResult &r); 
+                                      AssignmentConversionResult &r);
+  // Helper function for UsualAssignmentConversions
+  bool pointerTypeQualifiersAlign(QualType lhsType, QualType rhsType);
   
   /// the following "Check" methods will return a valid/converted QualType
   /// or a null QualType (indicating an error diagnostic was issued).

Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:24 2007
@@ -317,10 +317,10 @@
     unsigned NumArgsToCheck = NumArgsInCall;
     
     if (NumArgsInCall < NumArgsInProto)
-      Diag(LParenLoc, diag::ext_typecheck_call_too_few_args);
+      Diag(LParenLoc, diag::err_typecheck_call_too_few_args);
     else if (NumArgsInCall > NumArgsInProto) {
       if (!proto->isVariadic())
-        Diag(LParenLoc, diag::ext_typecheck_call_too_many_args);
+        Diag(LParenLoc, diag::err_typecheck_call_too_many_args);
       NumArgsToCheck = NumArgsInProto;
     }
     // Continue to check argument types (even if we have too few/many args).
@@ -353,6 +353,9 @@
       case IncompatiblePointer:
         Diag(l, diag::ext_typecheck_passing_incompatible_pointer, utostr(i+1));
         break;
+      case CompatiblePointerDiscardsQualifiers:
+        Diag(l, diag::ext_typecheck_passing_discards_qualifiers, utostr(i+1));
+        break;
       case Incompatible:
         return Diag(l, diag::err_typecheck_passing_incompatible, utostr(i+1));
       }
@@ -449,6 +452,39 @@
   return Context.maxIntegerType(lhs, rhs);
 }
 
+// C99 6.5.16.1p1: both operands are pointers to qualified or 
+// unqualified versions of compatible types, and the type *pointed to* by
+// the left has all the qualifiers of the type *pointed to* by the right;
+bool Sema::pointerTypeQualifiersAlign(QualType lhsType, QualType rhsType) {
+  QualType lPointee, rPointee;
+  
+  // get the "pointed to" type (ignoring qualifiers at the top level)
+  lPointee = cast<PointerType>(lhsType.getCanonicalType())->getPointeeType();
+  rPointee = cast<PointerType>(rhsType.getCanonicalType())->getPointeeType();
+  
+  // make sure we operate on the canonical type
+  lPointee = lPointee.getCanonicalType();
+  rPointee = rPointee.getCanonicalType();
+    
+  while (!rPointee.isNull() && !lPointee.isNull()) {
+    unsigned rightQuals = rPointee.getQualifiers();
+    if (rightQuals && (rightQuals != lPointee.getQualifiers()))
+      return false; 
+
+    // if necessary, continue checking pointees...
+    if (const PointerType *rPtr = dyn_cast<PointerType>(rPointee))
+      rPointee = rPtr->getPointeeType().getCanonicalType();
+    else
+      rPointee = QualType();
+      
+    if (const PointerType *lPtr = dyn_cast<PointerType>(lPointee))
+      lPointee = lPtr->getPointeeType().getCanonicalType();
+    else
+      rPointee = QualType();
+  }
+  return true;
+}
+
 /// UsualAssignmentConversions (C99 6.5.16) - This routine currently 
 /// has code to accommodate several GCC extensions when type checking 
 /// pointers. Here are some objectionable examples that GCC considers warnings:
@@ -483,9 +519,11 @@
       r = PointerFromInt;
       return rhsType;
     }
-    // FIXME: make sure the qualifier are matching
     if (rhsType->isPointerType()) { 
-      if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+      if (Type::pointerTypesAreCompatible(lhsType, rhsType)) {
+        if (!pointerTypeQualifiersAlign(lhsType, rhsType))
+          r = CompatiblePointerDiscardsQualifiers;
+      } else
         r = IncompatiblePointer;
       return rhsType;
     }
@@ -496,21 +534,18 @@
         r = IntFromPointer;
       return rhsType;
     }
-    // - both operands are pointers to qualified or unqualified versions of
-    // compatible types, and the type pointed to by the left has *all* the
-    // qualifiers of the type pointed to by the right;
     if (lhsType->isPointerType()) {
-      if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+      if (Type::pointerTypesAreCompatible(lhsType, rhsType)) {
+        if (!pointerTypeQualifiersAlign(lhsType, rhsType))
+          r = CompatiblePointerDiscardsQualifiers;
+      } else
         r = IncompatiblePointer;
       return rhsType;
     }
-  } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
-    if (Type::structureTypesAreCompatible(lhsType, rhsType))
+  } else if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
+    if (Type::tagTypesAreCompatible(lhsType, rhsType))
       return rhsType;
-  } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
-    if (Type::unionTypesAreCompatible(lhsType, rhsType))
-      return rhsType;
-  }
+  } 
   r = Incompatible;
   return QualType();
 }
@@ -644,18 +679,16 @@
 {
   QualType lhsType = lex->getType();
   QualType rhsType = compoundType.isNull() ? rex->getType() : compoundType;
-  
-  // FIXME: consider hacking isModifiableLvalue to return an enum that
-  // communicates why the expression/type wasn't a modifiableLvalue.
+  bool hadError = false;
   
   // this check is done first to give a more precise diagnostic.
+  // isModifiableLvalue() will also check for "const".
   if (lhsType.isConstQualified()) {
     Diag(loc, diag::err_typecheck_assign_const);
-    return QualType();
-  }
-  if (!lex->isModifiableLvalue()) { // this includes checking for "const"
-    Diag(loc, diag::ext_typecheck_assign_non_lvalue);
-    return QualType();
+    hadError = true;
+  } else if (!lex->isModifiableLvalue()) { // C99 6.5.16p2
+    Diag(loc, diag::err_typecheck_assign_non_lvalue);
+    return QualType(); // no need to continue checking...
   }
   if (lhsType == rhsType) // common case, fast path...
     return lhsType;
@@ -666,23 +699,27 @@
   // decode the result (notice that extensions still return a type).
   switch (result) {
   case Compatible:
-    return resType;
+    break;
   case Incompatible:
     Diag(loc, diag::err_typecheck_assign_incompatible);
-    return QualType();
+    hadError = true;
+    break;
   case PointerFromInt:
     // check for null pointer constant (C99 6.3.2.3p3)
     if (compoundType.isNull() && !rex->isNullPointerConstant())
       Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
-    return resType;
+    break;
   case IntFromPointer:
     Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
-    return resType;
+    break;
   case IncompatiblePointer:
     Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-    return resType;
+    break;
+  case CompatiblePointerDiscardsQualifiers:
+    Diag(loc, diag::ext_typecheck_assign_discards_qualifiers);
+    break;
   }
-  assert(0 && "should never get here");
+  return hadError ? QualType() : resType;
 }
 
 inline QualType Sema::CheckCommaOperands( // C99 6.5.17

Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:24 2007
@@ -74,7 +74,7 @@
 
 // C99 6.2.7p1: If both are complete types, then the following additional
 // requirements apply...FIXME (handle compatibility across source files).
-bool Type::structureTypesAreCompatible(QualType lhs, QualType rhs) {
+bool Type::tagTypesAreCompatible(QualType lhs, QualType rhs) {
   TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
   TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
   
@@ -82,13 +82,6 @@
     if (ldecl->getIdentifier() == rdecl->getIdentifier())
       return true;
   }
-  return false;
-}
-
-bool Type::unionTypesAreCompatible(QualType lhs, QualType rhs) {
-  TagDecl *ldecl = cast<TagType>(lhs.getCanonicalType())->getDecl();
-  TagDecl *rdecl = cast<TagType>(rhs.getCanonicalType())->getDecl();
-  
   if (ldecl->getKind() == Decl::Union && rdecl->getKind() == Decl::Union) {
     if (ldecl->getIdentifier() == rdecl->getIdentifier())
       return true;
@@ -99,7 +92,7 @@
 bool Type::pointerTypesAreCompatible(QualType lhs, QualType rhs) {
   QualType ltype = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
   QualType rtype = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
-  
+
   // handle void first (not sure this is the best place to check for this).
   if (ltype->isVoidType() || rtype->isVoidType())
     return true;
@@ -160,26 +153,39 @@
   return true;
 }
 
-bool Type::typesAreCompatible(QualType lcanon, QualType rcanon) {
+bool Type::typesAreCompatible(QualType lhs, QualType rhs) {
+  QualType lcanon = lhs.getCanonicalType();
+  QualType rcanon = rhs.getCanonicalType();
+
   // If two types are identical, they are are compatible
-  // C99 6.7.3p9: For two qualified types to be compatible, both shall have
-  // the identically qualified version of a compatible type.
   if (lcanon == rcanon)
     return true;
-    
-  if (lcanon->isStructureType() && rcanon->isStructureType())
-    return structureTypesAreCompatible(lcanon, rcanon);
-    
-  if (lcanon->isPointerType() && rcanon->isPointerType())
-    return pointerTypesAreCompatible(lcanon, rcanon);
+  
+  // If the canonical type classes don't match, they can't be compatible
+  if (lcanon->getTypeClass() != rcanon->getTypeClass())
+    return false;
 
-  if (lcanon->isArrayType() && rcanon->isArrayType())
-    return arrayTypesAreCompatible(lcanon, rcanon);
-    
-  if (lcanon->isFunctionType() && rcanon->isFunctionType())
-    return functionTypesAreCompatible(lcanon, rcanon);
-      
-  return false;
+  switch (lcanon->getTypeClass()) {
+    case Type::Pointer:
+      // C99 6.7.3p9: For two qualified types to be compatible, both shall have
+      // the identically qualified version of a compatible type. ??
+      return pointerTypesAreCompatible(lcanon, rcanon);
+    case Type::Array:
+      return arrayTypesAreCompatible(lcanon, rcanon);
+    case Type::FunctionNoProto:
+    case Type::FunctionProto:
+      return functionTypesAreCompatible(lcanon, rcanon);
+    case Type::Tagged: // handle structures, unions
+      return tagTypesAreCompatible(lcanon, rcanon);
+    case Type::Builtin:
+      // exclude type qualifiers...
+      if (lcanon.getTypePtr() == rcanon.getTypePtr())
+        return true;
+      return false; // C99 6.2.7p1
+    default:
+      assert(0 && "unexpected type");
+  }
+  return true; // should never get here...
 }
 
 bool Type::isIntegerType() const {
@@ -401,10 +407,13 @@
 // Type Printing
 //===----------------------------------------------------------------------===//
 
-void QualType::dump() const {
+void QualType::dump(const char *msg) const {
   std::string R = "foo";
   getAsString(R);
-  std::cerr << R << "\n";
+  if (msg)
+    std::cerr << msg << ": " << R << "\n";
+  else
+    std::cerr << R << "\n";
 }
 
 static void AppendTypeQualList(std::string &S, unsigned TypeQuals) {

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:44:24 2007
@@ -236,13 +236,16 @@
     Incompatible,
     PointerFromInt, 
     IntFromPointer,
-    IncompatiblePointer
+    IncompatiblePointer,
+    CompatiblePointerDiscardsQualifiers
   };
   // Conversions for assignment, argument passing, initialization, and
   // function return values. UsualAssignmentConversions is currently used by 
   // CheckSimpleAssignment, CheckCompoundAssignment and ParseCallExpr. 
   QualType UsualAssignmentConversions(QualType lhs, QualType rhs, // C99 6.5.16
-                                      AssignmentConversionResult &r); 
+                                      AssignmentConversionResult &r);
+  // Helper function for UsualAssignmentConversions
+  bool pointerTypeQualifiersAlign(QualType lhsType, QualType rhsType);
   
   /// the following "Check" methods will return a valid/converted QualType
   /// or a null QualType (indicating an error diagnostic was issued).

Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:24 2007
@@ -317,10 +317,10 @@
     unsigned NumArgsToCheck = NumArgsInCall;
     
     if (NumArgsInCall < NumArgsInProto)
-      Diag(LParenLoc, diag::ext_typecheck_call_too_few_args);
+      Diag(LParenLoc, diag::err_typecheck_call_too_few_args);
     else if (NumArgsInCall > NumArgsInProto) {
       if (!proto->isVariadic())
-        Diag(LParenLoc, diag::ext_typecheck_call_too_many_args);
+        Diag(LParenLoc, diag::err_typecheck_call_too_many_args);
       NumArgsToCheck = NumArgsInProto;
     }
     // Continue to check argument types (even if we have too few/many args).
@@ -353,6 +353,9 @@
       case IncompatiblePointer:
         Diag(l, diag::ext_typecheck_passing_incompatible_pointer, utostr(i+1));
         break;
+      case CompatiblePointerDiscardsQualifiers:
+        Diag(l, diag::ext_typecheck_passing_discards_qualifiers, utostr(i+1));
+        break;
       case Incompatible:
         return Diag(l, diag::err_typecheck_passing_incompatible, utostr(i+1));
       }
@@ -449,6 +452,39 @@
   return Context.maxIntegerType(lhs, rhs);
 }
 
+// C99 6.5.16.1p1: both operands are pointers to qualified or 
+// unqualified versions of compatible types, and the type *pointed to* by
+// the left has all the qualifiers of the type *pointed to* by the right;
+bool Sema::pointerTypeQualifiersAlign(QualType lhsType, QualType rhsType) {
+  QualType lPointee, rPointee;
+  
+  // get the "pointed to" type (ignoring qualifiers at the top level)
+  lPointee = cast<PointerType>(lhsType.getCanonicalType())->getPointeeType();
+  rPointee = cast<PointerType>(rhsType.getCanonicalType())->getPointeeType();
+  
+  // make sure we operate on the canonical type
+  lPointee = lPointee.getCanonicalType();
+  rPointee = rPointee.getCanonicalType();
+    
+  while (!rPointee.isNull() && !lPointee.isNull()) {
+    unsigned rightQuals = rPointee.getQualifiers();
+    if (rightQuals && (rightQuals != lPointee.getQualifiers()))
+      return false; 
+
+    // if necessary, continue checking pointees...
+    if (const PointerType *rPtr = dyn_cast<PointerType>(rPointee))
+      rPointee = rPtr->getPointeeType().getCanonicalType();
+    else
+      rPointee = QualType();
+      
+    if (const PointerType *lPtr = dyn_cast<PointerType>(lPointee))
+      lPointee = lPtr->getPointeeType().getCanonicalType();
+    else
+      rPointee = QualType();
+  }
+  return true;
+}
+
 /// UsualAssignmentConversions (C99 6.5.16) - This routine currently 
 /// has code to accommodate several GCC extensions when type checking 
 /// pointers. Here are some objectionable examples that GCC considers warnings:
@@ -483,9 +519,11 @@
       r = PointerFromInt;
       return rhsType;
     }
-    // FIXME: make sure the qualifier are matching
     if (rhsType->isPointerType()) { 
-      if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+      if (Type::pointerTypesAreCompatible(lhsType, rhsType)) {
+        if (!pointerTypeQualifiersAlign(lhsType, rhsType))
+          r = CompatiblePointerDiscardsQualifiers;
+      } else
         r = IncompatiblePointer;
       return rhsType;
     }
@@ -496,21 +534,18 @@
         r = IntFromPointer;
       return rhsType;
     }
-    // - both operands are pointers to qualified or unqualified versions of
-    // compatible types, and the type pointed to by the left has *all* the
-    // qualifiers of the type pointed to by the right;
     if (lhsType->isPointerType()) {
-      if (!Type::pointerTypesAreCompatible(lhsType, rhsType))
+      if (Type::pointerTypesAreCompatible(lhsType, rhsType)) {
+        if (!pointerTypeQualifiersAlign(lhsType, rhsType))
+          r = CompatiblePointerDiscardsQualifiers;
+      } else
         r = IncompatiblePointer;
       return rhsType;
     }
-  } else if (lhsType->isStructureType() && rhsType->isStructureType()) {
-    if (Type::structureTypesAreCompatible(lhsType, rhsType))
+  } else if (isa<TagType>(lhsType) && isa<TagType>(rhsType)) {
+    if (Type::tagTypesAreCompatible(lhsType, rhsType))
       return rhsType;
-  } else if (lhsType->isUnionType() && rhsType->isUnionType()) {
-    if (Type::unionTypesAreCompatible(lhsType, rhsType))
-      return rhsType;
-  }
+  } 
   r = Incompatible;
   return QualType();
 }
@@ -644,18 +679,16 @@
 {
   QualType lhsType = lex->getType();
   QualType rhsType = compoundType.isNull() ? rex->getType() : compoundType;
-  
-  // FIXME: consider hacking isModifiableLvalue to return an enum that
-  // communicates why the expression/type wasn't a modifiableLvalue.
+  bool hadError = false;
   
   // this check is done first to give a more precise diagnostic.
+  // isModifiableLvalue() will also check for "const".
   if (lhsType.isConstQualified()) {
     Diag(loc, diag::err_typecheck_assign_const);
-    return QualType();
-  }
-  if (!lex->isModifiableLvalue()) { // this includes checking for "const"
-    Diag(loc, diag::ext_typecheck_assign_non_lvalue);
-    return QualType();
+    hadError = true;
+  } else if (!lex->isModifiableLvalue()) { // C99 6.5.16p2
+    Diag(loc, diag::err_typecheck_assign_non_lvalue);
+    return QualType(); // no need to continue checking...
   }
   if (lhsType == rhsType) // common case, fast path...
     return lhsType;
@@ -666,23 +699,27 @@
   // decode the result (notice that extensions still return a type).
   switch (result) {
   case Compatible:
-    return resType;
+    break;
   case Incompatible:
     Diag(loc, diag::err_typecheck_assign_incompatible);
-    return QualType();
+    hadError = true;
+    break;
   case PointerFromInt:
     // check for null pointer constant (C99 6.3.2.3p3)
     if (compoundType.isNull() && !rex->isNullPointerConstant())
       Diag(loc, diag::ext_typecheck_assign_pointer_from_int);
-    return resType;
+    break;
   case IntFromPointer:
     Diag(loc, diag::ext_typecheck_assign_int_from_pointer);
-    return resType;
+    break;
   case IncompatiblePointer:
     Diag(loc, diag::ext_typecheck_assign_incompatible_pointer);
-    return resType;
+    break;
+  case CompatiblePointerDiscardsQualifiers:
+    Diag(loc, diag::ext_typecheck_assign_discards_qualifiers);
+    break;
   }
-  assert(0 && "should never get here");
+  return hadError ? QualType() : resType;
 }
 
 inline QualType Sema::CheckCommaOperands( // C99 6.5.17

Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:24 2007
@@ -120,7 +120,7 @@
   bool isModifiableLvalue() const;
     
   void getAsString(std::string &S) const;
-  void dump() const;
+  void dump(const char *s = 0) const;
 
   /// getCanonicalType - Return the canonical version of this type, with the
   /// appropriate type qualifiers on it.
@@ -238,8 +238,7 @@
 
   /// Compatibility predicates used to check assignment expressions.
   static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1
-  static bool structureTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
-  static bool unionTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
+  static bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1
   static bool pointerTypesAreCompatible(QualType, QualType);  // C99 6.7.5.1p2
   static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15
   static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6
@@ -248,7 +247,7 @@
   // knows if the type is const. This predicate is a helper to QualType. 
   bool isModifiableLvalue() const; // C99 6.3.2.1p1
   
-  QualType getCanonicalType() const { return CanonicalType; }
+  QualType getCanonicalTypeInternal() const { return CanonicalType; }
   friend class QualType;
 public:
   virtual void getAsString(std::string &InnerString) const = 0;
@@ -515,9 +514,9 @@
 /// getCanonicalType - Return the canonical version of this type, with the
 /// appropriate type qualifiers on it.
 inline QualType QualType::getCanonicalType() const {
-  return QualType(getTypePtr()->getCanonicalType().getTypePtr(),
+  return QualType(getTypePtr()->getCanonicalTypeInternal().getTypePtr(),
                   getQualifiers() |
-                  getTypePtr()->getCanonicalType().getQualifiers());
+                  getTypePtr()->getCanonicalTypeInternal().getQualifiers());
 }
   
 }  // end namespace clang

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39439&r1=39438&r2=39439&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:24 2007
@@ -559,11 +559,13 @@
      "assignment makes pointer from integer without a cast")
 DIAG(ext_typecheck_assign_incompatible_pointer, EXTENSION,
      "assignment from incompatible pointer type")
-DIAG(ext_typecheck_assign_non_lvalue, ERROR,
+DIAG(ext_typecheck_assign_discards_qualifiers, EXTENSION,
+     "assignment discards qualifiers from pointer target type")
+DIAG(err_typecheck_assign_non_lvalue, ERROR,
      "invalid lvalue in assignment")
-DIAG(ext_typecheck_call_too_few_args, ERROR,
+DIAG(err_typecheck_call_too_few_args, ERROR,
      "too few arguments to function")
-DIAG(ext_typecheck_call_too_many_args, ERROR,
+DIAG(err_typecheck_call_too_many_args, ERROR,
      "too many arguments to function")
 DIAG(err_typecheck_passing_incompatible, ERROR,
      "incompatible type for argument %s")
@@ -573,6 +575,8 @@
      "passing argument %s makes pointer from integer without a cast")
 DIAG(ext_typecheck_passing_incompatible_pointer, EXTENSION,
      "passing argument %s from incompatible pointer type")
+DIAG(ext_typecheck_passing_discards_qualifiers, EXTENSION,
+     "passing argument %s discards qualifiers from pointer target type")
 
 // Statements.
 DIAG(err_continue_not_in_loop, ERROR,





More information about the cfe-commits mailing list