aboutsummaryrefslogtreecommitdiff
path: root/lib
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 /lib
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
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h6
-rw-r--r--lib/Sema/SemaExpr.cpp21
2 files changed, 27 insertions, 0 deletions
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;