aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-11-07 20:20:40 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-11-07 20:20:40 +0000
commit36a862f1d6810e05121d5be1b6458bd11b69e495 (patch)
treeb4dcaa38c9a4536599f5d7c9d66083b5cc08148b
parent75711ecdd48fe4d26ea5e5bd8c294c882662d0cc (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaExpr.cpp21
3 files changed, 29 insertions, 0 deletions
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<VectorConversions>, 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<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;