From patchwork Sun Oct 24 09:05:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Sandoe X-Patchwork-Id: 69028 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 2EC65B6F11 for ; Sun, 24 Oct 2010 20:05:52 +1100 (EST) Received: (qmail 26288 invoked by alias); 24 Oct 2010 09:05:50 -0000 Received: (qmail 26274 invoked by uid 22791); 24 Oct 2010 09:05:47 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, TW_BJ X-Spam-Check-By: sourceware.org Received: from c2bthomr07.btconnect.com (HELO mail.btconnect.com) (213.123.20.125) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 24 Oct 2010 09:05:37 +0000 Received: from host81-138-1-83.in-addr.btopenworld.com (EHLO thor.office) ([81.138.1.83]) by c2bthomr07.btconnect.com with ESMTP id AQM57584; Sun, 24 Oct 2010 10:05:29 +0100 (BST) Message-Id: <3F894B1C-C5CE-45FD-B73F-843A2C7ED940@sandoe-acoustics.co.uk> From: IainS To: GCC Patches Mime-Version: 1.0 (Apple Message framework v936) Subject: [Patch, c* ,ObjC*] handle string objects in format checking. Date: Sun, 24 Oct 2010 10:05:21 +0100 Cc: Mike Stump , "Joseph S. Myers" X-Mirapoint-IP-Reputation: reputation=Fair-1, source=Queried, refid=tid=0001.0A0B0302.4CC3F6D1.01D5, actions=TAG X-Junkmail-Signature-Raw: score=unknown, refid=str=0001.0A0B0208.4CC3F6DE.001D, ss=1, fgs=0, ip=0.0.0.0, so=2010-07-22 22:03:31, dmn=2009-09-10 00:05:08, mode=single engine X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello, ObjC* (currently for NeXT, but potentially also with GNU runtime) can use string object references in format args. Darwin [and potentially other platforms, if the GNUstep people wish to implement] can also use CFStrings from c* in the same context (as these are essentially the same beast internally) and thus share with ObjC*. Since Dawin10 was released some important system headers make use of CFStringRefs, which is a bit of show-stopper for [c, c++ and ObjC*] CoreFoundation on Darwin10 -- this is PR44981. We have now implemented CFString on FSF gcc and this patch adds use of those in formatters. ObjC strings are implemented in the normal way, with function calls and a stub in stub-objc. CFString is handled with a c-family target hook. Clearly, the main part of this is darwin and ObjC*-specific... ** however we do need review and approval for the gcc/c-family changes. boostrapped & checked on darwin9 & 10 (clears the remaining header parse errors there) and on x86_64-unk-linux (to ensure no changes to objc results). OK for trunk? Iain gcc: PR target/44981 * doc/tm.texi: Document TARGET_STRING_OBJECT_REF_TYPE_P hook. * doc/tm.texi.in: TARGET_STRING_OBJECT_REF_TYPE_P: New. * c-family/c-format.c (format_type): Add gcc_objc_string_format_type. (valid_stringptr_type_p): New. (handle_format_arg_attribute): Use valid_stringptr_type_p(). (check_format_string): Likewise. (format_types_orig): Add NSString. * c-family/c-common.h (objc_string_ref_type_p): New prototype. * c-family/stub-objc.c: New stub. * config/darwin-c.c (darwin_cfstring_ref_p): New. * config/darwin-protos.h: Correct arg list for darwin_build_constant_cfstring() (darwin_cfstring_ref_p): New prototype. * config/darwin.c: Add c-format.h. (darwin_additional_format_types): New. * config/darwin.h: (TARGET_STRING_OBJECT_REF_TYPE_P) New. (TARGET_N_FORMAT_TYPES): New. (TARGET_FORMAT_TYPES): New. * target.def (string_object_ref_type_p): New hook. gcc/objc: PR target/44981 * objc/objc-act.c (objc_string_ref_type_p): New. gcc/testsuite: PR target/44981 * obj-c++.dg/property/property-2.m: Adjust for darwin10 linker warning. * obj-c++.dg/property/property-3.mm: Likewise. * obj-c++.dg/torture/strings/const-cfstring-1.mm: Likewise. * objc.dg/property/property-3.m: Likewise. * objc.dg/property/property-2.m: Likewise. * objc.dg/torture/strings/const-cfstring-1.m: Likewise. Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi (revision 165889) +++ gcc/doc/tm.texi (working copy) @@ -746,6 +746,10 @@ should use @code{TARGET_HANDLE_C_OPTION} instead. Construct a constant string representation for @var{string} @end deftypefn +@deftypefn {Target Hook} bool TARGET_STRING_OBJECT_REF_TYPE_P (const_tree @var{stringref}) +Check for a valid string object reference type in @var{stringref} +@end deftypefn + @defmac TARGET_VERSION This macro is a C statement to print on @code{stderr} a string describing the particular machine description choice. Every machine Index: gcc/doc/tm.texi.in =================================================================== --- gcc/doc/tm.texi.in (revision 165889) +++ gcc/doc/tm.texi.in (working copy) @@ -744,6 +744,8 @@ should use @code{TARGET_HANDLE_C_OPTION} instead. @hook TARGET_OBJC_CONSTRUCT_STRING +@hook TARGET_STRING_OBJECT_REF_TYPE_P + @defmac TARGET_VERSION This macro is a C statement to print on @code{stderr} a string describing the particular machine description choice. Every machine Index: gcc/c-family/c-format.c =================================================================== --- gcc/c-family/c-format.c (revision 165889) +++ gcc/c-family/c-format.c (working copy) @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "c-format.h" #include "alloc-pool.h" +#include "target.h" /* Set format warning options according to a -Wformat=n option. */ @@ -63,6 +64,7 @@ enum format_type { printf_format_type, asm_fprintf gcc_diag_format_type, gcc_tdiag_format_type, gcc_cdiag_format_type, gcc_cxxdiag_format_type, gcc_gfc_format_type, + gcc_objc_string_format_type, format_type_error = -1}; typedef struct function_format_info @@ -83,6 +85,19 @@ static bool get_constant (tree expr, unsigned HOST static const char *convert_format_name_to_system_name (const char *attr_name); static bool cmp_attribs (const char *tattr_name, const char *attr_name); +/* Check that we have a pointer to a string, or string object for objc and + targets that support them in c*. */ + +static bool +valid_stringptr_type_p (tree strp) +{ + return (strp != NULL + && TREE_CODE (strp) == POINTER_TYPE + && (TYPE_MAIN_VARIANT (TREE_TYPE (strp)) == char_type_node + || objc_string_ref_type_p (strp) + || (*targetcm.string_object_ref_type_p) ((const_tree)strp))); +} + /* Handle a "format_arg" attribute; arguments as in struct attribute_spec.handler. */ tree @@ -108,9 +123,7 @@ handle_format_arg_attribute (tree *node, tree ARG_ return NULL_TREE; } - if (TREE_CODE (TREE_TYPE (type)) != POINTER_TYPE - || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))) - != char_type_node)) + if (! valid_stringptr_type_p (TREE_TYPE (type))) { if (!(flags & (int) ATTR_FLAG_BUILT_IN)) error ("function does not return string type"); @@ -136,10 +149,8 @@ check_format_string (tree argument, unsigned HOST_ argument = TREE_CHAIN (argument); } - if (!argument - || TREE_CODE (TREE_VALUE (argument)) != POINTER_TYPE - || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (argument))) - != char_type_node)) + if (! argument + || !valid_stringptr_type_p (TREE_VALUE (argument))) { if (!(flags & (int) ATTR_FLAG_BUILT_IN)) error ("format string argument not a string type"); @@ -750,6 +761,11 @@ static const format_kind_info format_types_orig[] 0, 0, 0, 0, 0, 0, NULL, NULL }, + { "NSString", NULL, NULL, NULL, NULL, + NULL, NULL, + FMT_FLAG_ARG_CONVERT, 0, 0, 0, 0, 0, 0, + NULL, NULL + }, { "gnu_scanf", scanf_length_specs, scan_char_table, "*'I", NULL, scanf_flag_specs, scanf_flag_pairs, FMT_FLAG_ARG_CONVERT|FMT_FLAG_SCANF_A_KLUDGE|FMT_FLAG_USE_DOLLAR|FMT_FLAG_ZERO_WIDTH_BAD|FMT_FLAG_DOLLAR_GAP_POINTER_OK, Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 165889) +++ gcc/c-family/c-common.h (working copy) @@ -1049,6 +1049,7 @@ extern tree objc_build_setter_call (tree, tree); extern void objc_add_synthesize_declaration (location_t, tree); extern void objc_add_dynamic_declaration (location_t, tree); extern const char * objc_maybe_printable_name (tree, int); +extern bool objc_string_ref_type_p (tree); /* The following are provided by the C and C++ front-ends, and called by ObjC/ObjC++. */ Index: gcc/c-family/stub-objc.c =================================================================== --- gcc/c-family/stub-objc.c (revision 165889) +++ gcc/c-family/stub-objc.c (working copy) @@ -426,3 +426,9 @@ void objc_write_global_declarations (void) { } + +bool +objc_string_ref_type_p (tree ARG_UNUSED (strp)) +{ + return false; +} Index: gcc/config/darwin-c.c =================================================================== --- gcc/config/darwin-c.c (revision 165889) +++ gcc/config/darwin-c.c (working copy) @@ -678,3 +678,21 @@ darwin_objc_construct_string (tree str) return darwin_build_constant_cfstring (str); } + +/* The string ref type is created as CFStringRef by therefore, we + must match for it explicitly, since it's outside the gcc code. */ + +bool +darwin_cfstring_ref_p (const_tree strp) +{ + tree tn; + if (!strp || TREE_CODE (strp) != POINTER_TYPE) + return false; + + tn = TYPE_NAME (strp); + if (tn) + tn = DECL_NAME (tn); + return (tn + && IDENTIFIER_POINTER (tn) + && !strncmp (IDENTIFIER_POINTER (tn), "CFStringRef", 8)); +} Index: gcc/config/darwin-protos.h =================================================================== --- gcc/config/darwin-protos.h (revision 165889) +++ gcc/config/darwin-protos.h (working copy) @@ -96,7 +96,8 @@ extern void darwin_init_cfstring_builtins (unsigne extern tree darwin_fold_builtin (tree, int, tree *, bool); extern tree darwin_objc_construct_string (tree); extern bool darwin_cfstring_p (tree); -extern tree darwin_build_constant_cfstring (tree str); +extern bool darwin_cfstring_ref_p (const_tree); +extern tree darwin_build_constant_cfstring (tree); extern void darwin_enter_string_into_cfstring_table (tree); extern void darwin_asm_output_anchor (rtx symbol); Index: gcc/config/darwin.c =================================================================== --- gcc/config/darwin.c (revision 165889) +++ gcc/config/darwin.c (working copy) @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "obstack.h" #include "lto-streamer.h" +#include "c-family/c-format.h" /* Darwin supports a feature called fix-and-continue, which is used for rapid turn around debugging. When code is compiled with the @@ -2269,4 +2270,13 @@ darwin_enter_string_into_cfstring_table (tree str) } } +/* The extra format types we recognize. */ +const format_kind_info darwin_additional_format_types[] = { + { "CFString", NULL, NULL, NULL, NULL, + NULL, NULL, + FMT_FLAG_ARG_CONVERT, 0, 0, 0, 0, 0, 0, + NULL, NULL + } +}; + #include "gt-darwin.h" Index: gcc/config/darwin.h =================================================================== --- gcc/config/darwin.h (revision 165889) +++ gcc/config/darwin.h (working copy) @@ -1060,6 +1060,12 @@ __enable_execute_stack (void *addr) #define TARGET_OBJC_CONSTRUCT_STRING \ darwin_objc_construct_string +#define TARGET_STRING_OBJECT_REF_TYPE_P \ + darwin_cfstring_ref_p + +#define TARGET_N_FORMAT_TYPES 1 +#define TARGET_FORMAT_TYPES darwin_additional_format_types + #define TARGET_HAS_TARGETCM 1 #ifndef CROSS_DIRECTORY_STRUCTURE Index: gcc/objc/objc-act.c =================================================================== --- gcc/objc/objc-act.c (revision 165889) +++ gcc/objc/objc-act.c (working copy) @@ -11801,4 +11801,21 @@ objc_finish_foreach_loop (location_t location, tre /* Done by c-parser.c */ } +/* Return true if we have an NxString object pointer. + Implemented only for NSString Objects so far. */ + +bool +objc_string_ref_type_p (tree strp) +{ + tree tmv; + if (!strp || TREE_CODE (strp) != POINTER_TYPE) + return false; + + tmv = TYPE_MAIN_VARIANT (TREE_TYPE (strp)); + tmv = OBJC_TYPE_NAME (tmv); + return (tmv + && IDENTIFIER_POINTER (tmv) + && !strncmp (IDENTIFIER_POINTER (tmv), "NSString", 8)); +} + #include "gt-objc-objc-act.h" Index: gcc/target.def =================================================================== --- gcc/target.def (revision 165889) +++ gcc/target.def (working copy) @@ -2539,5 +2539,11 @@ DEFHOOK "Construct a constant string representation for @var{string}", tree, (tree string), NULL) - + +DEFHOOK +(string_object_ref_type_p, + "Check for a valid string object reference type in @var{stringref}", + bool, (const_tree stringref), + hook_bool_const_tree_false) + HOOK_VECTOR_END (C90_EMPTY_HACK) Index: gcc/testsuite/obj-c++.dg/property/property-2.mm =================================================================== --- gcc/testsuite/obj-c++.dg/property/property-2.mm (revision 165889) +++ gcc/testsuite/obj-c++.dg/property/property-2.mm (working copy) @@ -5,6 +5,9 @@ /* { dg-require-effective-target ilp32 } */ /* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ /* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writeable ones at this juncture. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations -Wl,-w" { target *-*-darwin[123]* } } */ #include #include Index: gcc/testsuite/obj-c++.dg/property/property-3.mm =================================================================== --- gcc/testsuite/obj-c++.dg/property/property-3.mm (revision 165889) +++ gcc/testsuite/obj-c++.dg/property/property-3.mm (working copy) @@ -6,6 +6,9 @@ /* { dg-require-effective-target ilp32 } */ /* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ /* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writeable ones at this juncture. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations -Wl,-w" { target *-*-darwin[123]* } } */ #include #include Index: gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-1.mm =================================================================== --- gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-1.mm (revision 165889) +++ gcc/testsuite/obj-c++.dg/torture/strings/const-cfstring-1.mm (working copy) @@ -9,6 +9,9 @@ /* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ /* { dg-options "-mconstant-cfstrings -framework Cocoa" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writable ones at this juncture. */ +/* { dg-options "-mconstant-cfstrings -framework Cocoa -Wl,-w" { target *-*-darwin[123]* } } */ #import #import Index: gcc/testsuite/objc.dg/property/property-3.m =================================================================== --- gcc/testsuite/objc.dg/property/property-3.m (revision 165889) +++ gcc/testsuite/objc.dg/property/property-3.m (working copy) @@ -6,6 +6,9 @@ /* { dg-require-effective-target ilp32 } */ /* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ /* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writeable ones at this juncture. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations -Wl,-w" { target *-*-darwin[123]* } } */ #include #include Index: gcc/testsuite/objc.dg/property/property-2.m =================================================================== --- gcc/testsuite/objc.dg/property/property-2.m (revision 165889) +++ gcc/testsuite/objc.dg/property/property-2.m (working copy) @@ -6,6 +6,9 @@ /* { dg-require-effective-target ilp32 } */ /* Force ABI = 0 in the NeXT headers, also suppress deprecation warnings. */ /* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writeable ones at this juncture. */ +/* { dg-options "-framework Foundation -fobjc-exceptions -mmacosx-version-min=10.4 -Wno-deprecated-declarations -Wl,-w" { target *-*-darwin[123]* } } */ #include #include Index: gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m =================================================================== --- gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m (revision 165889) +++ gcc/testsuite/objc.dg/torture/strings/const-cfstring-1.m (working copy) @@ -9,6 +9,9 @@ /* { dg-skip-if "NeXT only" { *-*-* } { "-fgnu-runtime" } { "" } } */ /* { dg-xfail-run-if "Needs OBJC2 ABI" { *-*-darwin* && { lp64 && { ! objc2 } } } { "-fnext-runtime" } { "" } } */ /* { dg-options "-mconstant-cfstrings -framework Cocoa" } */ +/* Darwin10's linker emits a warning that the constant strings are incompatible with writable ones. + well, we don't implement writable ones at this juncture. */ +/* { dg-options "-mconstant-cfstrings -framework Cocoa -Wl,-w" { target *-*-darwin[123]* } } */ #import #import