aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-03-22 23:59:44 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-03-22 23:59:44 +0000
commitf05c05d2e1a2952e6cc7c3e54366fb8d99ff579c (patch)
tree168f9f815fe3637ac950512021d1e2aad205c8dc /lib
parent3fe51c49b2f6fa592cf94d038d149071b55ac7fe (diff)
Partial implementation of PR3342: break out pointer sign
incompatibilities in assignments from other pointer incompatibilities. Based off of the patch in PR3342. (This doesn't implement -Wno-pointer-sign, but I don't know the driver code very well.) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67494 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaExpr.cpp33
2 files changed, 37 insertions, 4 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 64cc088e96..8bc5a6073b 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2146,7 +2146,13 @@ public:
/// IncompatiblePointer - The assignment is between two pointers types that
/// are not compatible, but we accept them as an extension.
IncompatiblePointer,
-
+
+ /// IncompatiblePointer - The assignment is between two pointers types which
+ /// point to integers which have a different sign, but are otherwise identical.
+ /// This is a subset of the above, but broken out because it's by far the most
+ /// common case of incompatible pointers.
+ IncompatiblePointerSign,
+
/// CompatiblePointerDiscardsQualifiers - The assignment discards
/// c/v/r qualifiers, which we accept as an extension.
CompatiblePointerDiscardsQualifiers,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3220a9e461..85d28a83c7 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2792,9 +2792,33 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
}
// C99 6.5.16.1p1 (constraint 3): both operands are pointers to qualified or
// unqualified versions of compatible types, ...
- if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(),
- rhptee.getUnqualifiedType()))
- return IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
+ lhptee = lhptee.getUnqualifiedType();
+ rhptee = rhptee.getUnqualifiedType();
+ if (!Context.typesAreCompatible(lhptee, rhptee)) {
+ // Check if the pointee types are compatible ignoring the sign.
+ // We explicitly check for char so that we catch "char" vs
+ // "unsigned char" on systems where "char" is unsigned.
+ if (lhptee->isCharType()) {
+ lhptee = Context.UnsignedCharTy;
+ } else if (lhptee->isSignedIntegerType()) {
+ lhptee = Context.getCorrespondingUnsignedType(lhptee);
+ }
+ if (rhptee->isCharType()) {
+ rhptee = Context.UnsignedCharTy;
+ } else if (rhptee->isSignedIntegerType()) {
+ rhptee = Context.getCorrespondingUnsignedType(rhptee);
+ }
+ if (lhptee == rhptee) {
+ // Types are compatible ignoring the sign. Qualifier incompatibility
+ // takes priority over sign incompatibility because the sign
+ // warning can be disabled.
+ if (ConvTy != Compatible)
+ return ConvTy;
+ return IncompatiblePointerSign;
+ }
+ // General pointer incompatibility takes priority over qualifiers.
+ return IncompatiblePointer;
+ }
return ConvTy;
}
@@ -4629,6 +4653,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
case IncompatiblePointer:
DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
break;
+ case IncompatiblePointerSign:
+ DiagKind = diag::ext_typecheck_convert_incompatible_pointer_sign;
+ break;
case FunctionVoidPointer:
DiagKind = diag::ext_typecheck_convert_pointer_void_func;
break;