From: Fariborz Jahanian Date: Sat, 7 Nov 2009 20:20:40 +0000 (+0000) Subject: Patch to gives an error that at least points users in the direction of the error... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=36a862f1d6810e05121d5be1b6458bd11b69e495;p=clang Patch to gives an error that at least points users in the direction of the error, rather 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 29b207927f..1d0b97654c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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, DefaultIgnore; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 45d6b57437..84d4c598b2 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 9a549f1ff7..a09f6a9005 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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()->getPointeeType(); + rhptee = rhptee->getAs()->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;