summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Sema/Sema.h32
-rw-r--r--Sema/SemaExpr.cpp11
-rw-r--r--include/clang/Basic/DiagnosticKinds.def4
-rw-r--r--test/Parser/implicit-casts.c2
-rw-r--r--test/Sema/argument-checking.m6
-rw-r--r--test/Sema/array-init.c6
-rw-r--r--test/Sema/builtins.c2
-rw-r--r--test/Sema/objc-comptypes-7.m12
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 *'}}