]> granicus.if.org Git - clang/commitdiff
Patch to gives an error that at least points users in the direction of the error...
authorFariborz Jahanian <fjahanian@apple.com>
Sat, 7 Nov 2009 20:20:40 +0000 (20:20 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Sat, 7 Nov 2009 20:20:40 +0000 (20:20 +0000)
than an error about incompatible types. Patch by Sean Hunt.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp

index 29b207927f2802e21ca14ec13fa1377e3ba219f5..1d0b97654c64c8b9fdeb8ad46ef2068ad50a41da 100644 (file)
@@ -1839,6 +1839,8 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn<
   "incompatible pointer types %2 %1, expected %0">;
 def ext_typecheck_convert_discards_qualifiers : ExtWarn<
   "%2 %1 discards qualifiers, expected %0">;
+def err_multi_pointer_qualifier_mismatch : Error<
+  "%2, %0 and %1 have different qualifiers in a multi-level pointer chain">;
 def warn_incompatible_vectors : Warning<
   "incompatible vector types %2 %1, expected %0">,
   InGroup<VectorConversions>, DefaultIgnore;
index 45d6b57437dd122368a08d6ea36c6933f379661c..84d4c598b2c1427f4c52b044eab612269d2a46e5 100644 (file)
@@ -3485,6 +3485,12 @@ public:
     /// CompatiblePointerDiscardsQualifiers - The assignment discards
     /// c/v/r qualifiers, which we accept as an extension.
     CompatiblePointerDiscardsQualifiers,
+    
+    /// IncompatibleMultiPointerQualifiers - The assignment is between two
+    /// multi-level pointer types, and the qualifiers other than the first two
+    /// levels differ e.g. char ** -> const char **. We disallow this.
+    /// FIXME: GCC only warns for this - should we do the same?
+    IncompatibleMultiPointerQualifiers,
 
     /// IncompatibleVectors - The assignment is between two vector types that
     /// have the same size, which we accept as an extension.
index 9a549f1ff7302bc7f23769975c6e06f00af38562..a09f6a9005e4a504bc55bcea2aec6384d0230d4d 100644 (file)
@@ -3747,6 +3747,24 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
         return ConvTy;
       return IncompatiblePointerSign;
     }
+    
+    // If we are a multi-level pointer, it's possible that our issue is simply
+    // one of qualification - e.g. char ** -> const char ** is not allowed. If
+    // the eventual target type is the same and the pointers have the same
+    // level of indirection, this must be the issue.
+    if (lhptee->isPointerType() && rhptee->isPointerType()) {
+      do {
+        lhptee = lhptee->getAs<PointerType>()->getPointeeType();
+        rhptee = rhptee->getAs<PointerType>()->getPointeeType();
+      
+        lhptee = Context.getCanonicalType(lhptee);
+        rhptee = Context.getCanonicalType(rhptee);
+      } while (lhptee->isPointerType() && rhptee->isPointerType());
+      
+      if (lhptee.getUnqualifiedType() == rhptee.getUnqualifiedType())
+        return IncompatibleMultiPointerQualifiers;
+    }
+    
     // General pointer incompatibility takes priority over qualifiers.
     return IncompatiblePointer;
   }
@@ -6223,6 +6241,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
       return false;
     DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
     break;
+  case IncompatibleMultiPointerQualifiers:
+    DiagKind = diag::err_multi_pointer_qualifier_mismatch;
+    break;
   case IntToBlockPointer:
     DiagKind = diag::err_int_to_block_pointer;
     break;