diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ee7de8e7098f4e2c9142b13f30993814d0d9d72..015420446ecd0227d8178be97cadd9c2cddb83f7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,11 @@ -2009-03-28 Adam Nemet <anemet@caviumnetworks.com> +2009-03-29 David Ayers <ayers@fsfe.org> + + PR objc/27377 + * c-typeck.c (build_conditional_expr): Emit ObjC warnings + by calling objc_compare_types and surpress warnings about + incompatible C pointers that are compatible ObjC pointers. + +2009-03-29 Adam Nemet <anemet@caviumnetworks.com> * cgraphbuild.c (build_cgraph_edges, rebuild_cgraph_edges): Don't call initialize_inline_failed. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 83188baf22f6c754769ea7d7affd4f80d7375e62..4b5fa0eac1ee4de2c91d3e0c8c1d2404790c9b47 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -3437,6 +3437,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) enum tree_code code2; tree result_type = NULL; tree orig_op1 = op1, orig_op2 = op2; + bool objc_ok; /* Promote both alternatives. */ @@ -3463,6 +3464,8 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) return error_mark_node; } + objc_ok = objc_compare_types (type1, type2, -3, NULL_TREE); + /* Quickly detect the usual case where op1 and op2 have the same type after promotion. */ if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) @@ -3546,8 +3549,9 @@ build_conditional_expr (tree ifexp, tree op1, tree op2) } else { - pedwarn (input_location, 0, - "pointer type mismatch in conditional expression"); + if (!objc_ok) + pedwarn (input_location, 0, + "pointer type mismatch in conditional expression"); result_type = build_pointer_type (void_type_node); } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b1d82e189c45ad60bbc93cc32f3b9e13b6cd6f1b..16415c6e60dc05a664fc5e90dbf8a61f4abdf6f0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-03-29 David Ayers <ayers@fsfe.org> + + PR objc/27377 + * objc.dg/conditional-1.m: New tests. + 2009-03-28 Adam Nemet <anemet@caviumnetworks.com> * gcc.dg/winline-10.c: New test. diff --git a/gcc/testsuite/objc.dg/conditional-1.m b/gcc/testsuite/objc.dg/conditional-1.m new file mode 100644 index 0000000000000000000000000000000000000000..0aad62c55f180b2621dd37d32bb0f719648d1753 --- /dev/null +++ b/gcc/testsuite/objc.dg/conditional-1.m @@ -0,0 +1,45 @@ +/* Testing conditional warnings (without headers). */ +/* Author: David Ayers */ + +/* { dg-do compile } */ + +#define nil ((id)0) +@interface MyObject +@end + +@protocol MyProtocol +@end + +@interface MyProtoObject <MyProtocol> +@end + + +int +main (int argc, char *argv[]) +{ + id var_id = nil; + id <MyProtocol> var_id_p = nil; + MyObject *var_obj = nil; + MyProtoObject *var_obj_p = nil; + + var_id = (var_id == var_obj) ? var_id : var_obj; + var_id = (var_id == var_obj) ? var_id : var_obj_p; + + /* Ayers: Currently, the following test case passes for + technically the wrong reason (see below). + */ + var_obj_p = (var_id == var_obj) ? var_obj_p : var_obj; /* { dg-warning "distinct Objective-C types" } */ + var_obj_p = (var_id == var_obj) ? var_obj_p : var_id_p; + + /* Ayers: The first of the following test cases + should probably warn for var_obj_p = var_obj, + yet that would require extensive changes to + build_conditional_expr to create a tree with + multiple types that the assignment would have + to evaluate both versions for correct diagnostics. + */ + var_obj_p = (var_id == var_obj) ? var_id : var_obj; + var_obj_p = (var_id == var_obj) ? var_id : var_obj_p; + + return 0; +}