diff options
-rw-r--r-- | Sema/Sema.h | 32 | ||||
-rw-r--r-- | Sema/SemaExpr.cpp | 11 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 4 | ||||
-rw-r--r-- | test/Parser/implicit-casts.c | 2 | ||||
-rw-r--r-- | test/Sema/argument-checking.m | 6 | ||||
-rw-r--r-- | test/Sema/array-init.c | 6 | ||||
-rw-r--r-- | test/Sema/builtins.c | 2 | ||||
-rw-r--r-- | test/Sema/objc-comptypes-7.m | 12 |
8 files changed, 52 insertions, 23 deletions
diff --git a/Sema/Sema.h b/Sema/Sema.h index e790a74251..d8871d2a38 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -613,13 +613,39 @@ private: // responsible for emitting appropriate error diagnostics. QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr, bool isCompAssign = false); + + /// AssignConvertType - All of the 'assignment' semantic checks return this + /// enum to indicate whether the assignment was allowed. These checks are + /// done for simple assignments, as well as initialization, return from + /// function, argument passing, etc. The query is phrased in terms of a + /// source and destination type. enum AssignConvertType { + /// Compatible - the types are compatible according to the standard. Compatible, - Incompatible, - PointerInt, + + /// PointerToInt - The assignment converts a pointer to an int, which we + /// accept as an extension. + PointerToInt, + + /// IntToPointer - The assignment converts an int to a pointer, which we + /// accept as an extension. + IntToPointer, + + /// FunctionVoidPointer - The assignment is between a function pointer and + /// void*, which the standard doesn't allow, but we accept as an extension. FunctionVoidPointer, + + /// IncompatiblePointer - The assignment is between two pointers types that + /// are not compatible, but we accept them as an extension. IncompatiblePointer, - CompatiblePointerDiscardsQualifiers + + /// CompatiblePointerDiscardsQualifiers - The assignment discards + /// c/v/r qualifiers, which we accept as an extension. + CompatiblePointerDiscardsQualifiers, + + /// Incompatible - We reject this conversion outright, it is invalid to + /// represent it in the AST. + Incompatible }; /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 7ed0bf102a..d41e2198c3 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -1087,8 +1087,6 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { /// Sema::AssignConvertType Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { - - if (lhsType.getCanonicalType().getUnqualifiedType() == rhsType.getCanonicalType().getUnqualifiedType()) return Compatible; // common case, fast path... @@ -1131,14 +1129,14 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { return Compatible; } else if (lhsType->isPointerType()) { if (rhsType->isIntegerType()) - return PointerInt; + return IntToPointer; if (rhsType->isPointerType()) return CheckPointerTypesForAssignment(lhsType, rhsType); } else if (rhsType->isPointerType()) { // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer. if ((lhsType->isIntegerType()) && (lhsType != Context.BoolTy)) - return PointerInt; + return PointerToInt; if (lhsType->isPointerType()) return CheckPointerTypesForAssignment(lhsType, rhsType); @@ -2139,9 +2137,12 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, switch (ConvTy) { default: assert(0 && "Unknown conversion type"); case Compatible: return false; - case PointerInt: + case PointerToInt: DiagKind = diag::ext_typecheck_convert_pointer_int; break; + case IntToPointer: + DiagKind = diag::ext_typecheck_convert_int_pointer; + break; case IncompatiblePointer: DiagKind = diag::ext_typecheck_convert_incompatible_pointer; break; diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 891d9317e0..97d58382af 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -768,7 +768,9 @@ DIAG(err_typecheck_assign_const, ERROR, DIAG(err_typecheck_convert_incompatible, ERROR, "incompatible type %2 '%1', expected '%0'") DIAG(ext_typecheck_convert_pointer_int, EXTENSION, - "incompatible pointer/int conversion %2 '%1', expected '%0'") + "incompatible pointer to integer conversion %2 '%1', expected '%0'") +DIAG(ext_typecheck_convert_int_pointer, EXTENSION, + "incompatible integer to pointer conversion %2 '%1', expected '%0'") DIAG(ext_typecheck_convert_pointer_void_func, EXTENSION, "%2 '%1' converts between void* and function pointer, expected '%0'") DIAG(ext_typecheck_convert_incompatible_pointer, EXTENSION, diff --git a/test/Parser/implicit-casts.c b/test/Parser/implicit-casts.c index 3d055263bc..1636f4993e 100644 --- a/test/Parser/implicit-casts.c +++ b/test/Parser/implicit-casts.c @@ -14,7 +14,7 @@ void test2() { } int test3() { int a[2]; - a[0] = test3; // expected-warning{{incompatible pointer/int conversion assigning 'int (void)', expected 'int'}} + a[0] = test3; // expected-warning{{incompatible pointer to integer conversion assigning 'int (void)', expected 'int'}} } short x; void test4(char c) { x += c; } int y; void test5(char c) { y += c; } diff --git a/test/Sema/argument-checking.m b/test/Sema/argument-checking.m index cd84171ee7..45eba87804 100644 --- a/test/Sema/argument-checking.m +++ b/test/Sema/argument-checking.m @@ -16,10 +16,10 @@ void test() { id obj = [Test alloc]; struct S sInst; - charStarFunc(1); // expected-warning {{incompatible pointer/int conversion passing 'int', expected 'char *'}} - charFunc("abc"); // expected-warning {{incompatible pointer/int conversion passing 'char *', expected 'char'}} + charStarFunc(1); // expected-warning {{incompatible integer to pointer conversion passing 'int', expected 'char *'}} + charFunc("abc"); // expected-warning {{incompatible pointer to integer conversion passing 'char *', expected 'char'}} - [obj charStarMeth:1]; // expected-warning {{incompatible pointer/int conversion sending 'int'}} + [obj charStarMeth:1]; // expected-warning {{incompatible integer to pointer conversion sending 'int'}} [obj structMeth:1]; // expected-error {{incompatible type sending 'int'}} [obj structMeth:sInst :1]; // expected-error {{incompatible type sending 'int'}} } diff --git a/test/Sema/array-init.c b/test/Sema/array-init.c index 1875fab389..af4b04b725 100644 --- a/test/Sema/array-init.c +++ b/test/Sema/array-init.c @@ -9,7 +9,7 @@ int ary2[] = { x, y, z }; // expected-error{{initializer element is not constant extern int fileScopeExtern[3] = { 1, 3, 5 }; // expected-warning{{'extern' variable has an initializer}} -static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible pointer/int conversion initializing 'char *', expected 'int'}} +static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible pointer to integer conversion initializing 'char *', expected 'int'}} void func() { int x = 1; @@ -44,11 +44,11 @@ void func() { int a,b,c; } z = { 1 }; - struct threeElements *p = 7; // expected-warning{{incompatible pointer/int conversion initializing 'int', expected 'struct threeElements *'}} + struct threeElements *p = 7; // expected-warning{{incompatible integer to pointer conversion initializing 'int', expected 'struct threeElements *'}} extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}} - static int x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible pointer/int conversion initializing 'char *', expected 'int'}} + static int x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible pointer to integer conversion initializing 'char *', expected 'int'}} } void test() { diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c index 59a339ad45..ca3cbaf8dc 100644 --- a/test/Sema/builtins.c +++ b/test/Sema/builtins.c @@ -26,7 +26,7 @@ int test6(float a, long double b) { void cfstring() { CFSTR("\242"); // expected-warning {{ CFString literal contains non-ASCII character }} CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }} - CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible pointer/int conversion}} + CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible integer to pointer conversion}} CFSTR("foo", "bar"); // expected-error {{ error: too many arguments to function }} } diff --git a/test/Sema/objc-comptypes-7.m b/test/Sema/objc-comptypes-7.m index 9d8f211da6..3e6a9d3434 100644 --- a/test/Sema/objc-comptypes-7.m +++ b/test/Sema/objc-comptypes-7.m @@ -23,22 +23,22 @@ int main() /* These should all generate warnings. */ - obj = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'id'}} + obj = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'id'}} obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}} obj_p = i; // expected-error {{incompatible type assigning 'int', expected 'id<MyProtocol>' }} obj_p = j; // expected-error {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}} - obj_c = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'MyClass *'}} + obj_c = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'MyClass *'}} obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}} - obj_C = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'Class'}} + obj_C = i; // expected-warning {{incompatible integer to pointer conversion assigning 'int', expected 'Class'}} obj_C = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'Class'}} - i = obj; // expected-warning {{incompatible pointer/int conversion assigning 'id', expected 'int'}} + i = obj; // expected-warning {{incompatible pointer to integer conversion assigning 'id', expected 'int'}} i = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int'}} - i = obj_c; // expected-warning {{incompatible pointer/int conversion assigning 'MyClass *', expected 'int'}} - i = obj_C; // expected-warning {{incompatible pointer/int conversion assigning 'Class', expected 'int'}} + i = obj_c; // expected-warning {{incompatible pointer to integer conversion assigning 'MyClass *', expected 'int'}} + i = obj_C; // expected-warning {{incompatible pointer to integer conversion assigning 'Class', expected 'int'}} j = obj; // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}} j = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}} |