From patchwork Mon Nov 29 02:28:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicola Pero X-Patchwork-Id: 73364 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 48EF9B6EED for ; Mon, 29 Nov 2010 13:28:32 +1100 (EST) Received: (qmail 20563 invoked by alias); 29 Nov 2010 02:28:30 -0000 Received: (qmail 20551 invoked by uid 22791); 29 Nov 2010 02:28:27 -0000 X-SWARE-Spam-Status: No, hits=-0.0 required=5.0 tests=AWL, BAYES_50, TW_BJ, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from fencepost.gnu.org (HELO fencepost.gnu.org) (140.186.70.10) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 29 Nov 2010 02:28:21 +0000 Received: from eggs.gnu.org ([140.186.70.92]:37990) by fencepost.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.69) (envelope-from ) id 1PMtTU-0001m7-PM for gcc-patches@gnu.org; Sun, 28 Nov 2010 21:28:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PMtTU-0001Np-TA for gcc-patches@gnu.org; Sun, 28 Nov 2010 21:28:18 -0500 Received: from smtp161.iad.emailsrvr.com ([207.97.245.161]:44814) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PMtTU-0001Nl-Ny for gcc-patches@gnu.org; Sun, 28 Nov 2010 21:28:16 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by smtp46.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id 4E1ECE8322 for ; Sun, 28 Nov 2010 21:28:16 -0500 (EST) Received: from dynamic4.wm-web.iad.mlsrvr.com (dynamic4.wm-web.iad1a.rsapps.net [192.168.2.153]) by smtp46.relay.iad1a.emailsrvr.com (SMTP Server) with ESMTP id 3CACDE831F for ; Sun, 28 Nov 2010 21:28:16 -0500 (EST) Received: from meta-innovation.com (localhost [127.0.0.1]) by dynamic4.wm-web.iad.mlsrvr.com (Postfix) with ESMTP id F26A81D4A26B for ; Sun, 28 Nov 2010 21:28:15 -0500 (EST) Received: by www2.webmail.us (Authenticated sender: nicola.pero@meta-innovation.com, from: nicola.pero@meta-innovation.com) with HTTP; Mon, 29 Nov 2010 03:28:15 +0100 (CET) Date: Mon, 29 Nov 2010 03:28:15 +0100 (CET) Subject: ObjC++: fix testcase failures on Darwin From: "Nicola Pero" To: "gcc-patches@gnu.org" MIME-Version: 1.0 X-Type: plain Message-ID: <1290997695.991412057@192.168.2.229> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) 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 This patch fixes the 5 @try/@catch ObjC++ testsuite failures on Darwin (Apple) with the NeXT runtime. The problem is with the artificially volatilized types that are used when setjmp/longjmp ObjC exception handling is being used (this currently happens only on Darwin with the NeXT runtime). The code we "inherited" from Apple flagged these artificially volatilized types using an attribute ("objc_volatilized") but the problem is that newer GCCs are smarted and consider attributes when building variants of types. So the additional attribute actually confuses the type system (for example, if you start with a non-volatilized 'int' type, and build the artificially volatilized variant, and then you try to get a non-volatile type variant using build_qualified_type(), you don't get the original type but a new 'int' type which preserves your new objc_volatilized attribute. This new 'int' is identical to the normal 'int' though, except for the 'objc_volatilized' attribute, but has a different canonical type. The C++ frontend detects this inconsistency and aborts). So, in the end I created a new TYPE_ARTIFICIALLY_VOLATILIZED() flag that can be used for types (I used the base.side_effects flag which is unused for types in C/ObjC/C++/ObjC++), and used it to mark our artificially volatilized types. Then the type system works again and everything seems to work with the next runtime, with the exception of two warnings in try-catch-12.m. These occur when a real 'volatile' variable is encountered in the same context as artificially volatilized ones, and if certain conditions are met the two types can get confused and some warnings for the real volatile variable may not be produced. To fix this, either we think of a completely different way of doing everything, or we may need to push some (or a lot of) awareness of TYPE_ARTIFICIALLY_VOLATILIZED() into tree.c. This should be a separate patch; in the meanwhile I'd suggest we xfail the test and open a PR so we don't forget about the problem. Anyway, all in all we're down from 5 hard compilation failures to 2 missed minor warnings (for unusual cases), which seems a good improvement. Ok to commit ? Thanks In gcc/: 2010-11-29 Nicola Pero * tree.h (TYPE_ARTIFICIALLY_VOLATILIZED): New. In gcc/objc/: 2010-11-29 Nicola Pero * objc-act.c (objc_get_volatilized_type): New. (objc_get_non_volatilized_type): New. (objc_build_volatilized_type): Use objc_get_volatilized_type. Duplicate ObjC type information when building the volatilized type. Set TYPE_ARTIFICIALLY_VOLATILIZED for the new type. (objc_non_volatilized_type): Use objc_get_non_volatilized_type. Index: gcc/tree.h =================================================================== --- gcc/tree.h (revision 167220) +++ gcc/tree.h (working copy) @@ -535,6 +535,9 @@ struct GTY(()) tree_common { FORCED_LABEL in LABEL_DECL + ARTIFICIALLY_VOLATILIZED in + all types + volatile_flag: TREE_THIS_VOLATILE in @@ -1234,6 +1237,13 @@ extern void omp_clause_range_check_faile computed gotos. */ #define FORCED_LABEL(NODE) (LABEL_DECL_CHECK (NODE)->base.side_effects_flag) +/* In a _TYPE, nonzero means that the type was artificially made + volatile for the purpose of code generation when using ObjC/ObjC++ + setjmp/longjmp exceptions (currently only on Darwin). So the _TYPE + is volatile, but we want to disable all warnings about assigning to + it to/from non-volatile variables. */ +#define TYPE_ARTIFICIALLY_VOLATILIZED(NODE) (TYPE_CHECK (NODE)->base.side_effects_flag) + /* Nonzero means this expression is volatile in the C sense: its address should be of type `volatile WHATEVER *'. In other words, the declared item is volatile qualified. Index: gcc/objc/objc-act.c =================================================================== --- gcc/objc/objc-act.c (revision 167231) +++ gcc/objc/objc-act.c (working copy) @@ -2260,49 +2260,135 @@ objc_build_struct (tree klass, tree fiel return s; } -/* Build a type differing from TYPE only in that TYPE_VOLATILE is set. - Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the - process. */ +/* Search for an existing type which is identical to TYPE but has + TYPE_VOLATILE and TYPE_ARTIFICIALLY_VOLATILIZED set. Return + NULL_TREE if no such type was found. */ static tree -objc_build_volatilized_type (tree type) +objc_get_volatilized_type (tree type) { - tree t; + tree t, volatilized_pointee = NULL_TREE; + + /* See if we already have the appropriate variant. */ + if (TYPE_ARTIFICIALLY_VOLATILIZED (type)) + return type; + + /* If we have a pointer, find the volatilized type for the pointee + first. When we build a volatilized type, we volatilize the + pointee as well. */ + if (POINTER_TYPE_P (type)) + { + volatilized_pointee = objc_get_volatilized_type (TREE_TYPE (type)); + + /* If there is none, we never built a volatilized type for the + pointer either (otherwise, there would be one). */ + if (volatilized_pointee == NULL_TREE) + return NULL_TREE; + } /* Check if we have not constructed the desired variant already. */ for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) { - /* The type qualifiers must (obviously) match up. */ - if (!TYPE_VOLATILE (t) - || (TYPE_READONLY (t) != TYPE_READONLY (type)) - || (TYPE_RESTRICT (t) != TYPE_RESTRICT (type))) + if (!TYPE_ARTIFICIALLY_VOLATILIZED (t)) continue; - /* For pointer types, the pointees (and hence their TYPE_LANG_SPECIFIC - info, if any) must match up. */ - if (POINTER_TYPE_P (t) - && (TREE_TYPE (t) != TREE_TYPE (type))) + if (!check_qualified_type + (t, type, (TYPE_QUALS (type) | TYPE_QUAL_VOLATILE))) continue; + + /* For pointer types, the pointees (and hence their + TYPE_LANG_SPECIFIC info, if any) must match up. */ + if (POINTER_TYPE_P (t)) + { + if (TREE_TYPE (t) != volatilized_pointee) + continue; + } + + /* Everything matches up! */ + return t; + } + + return NULL_TREE; +} + +/* Search for an existing type which is identical to TYPE but has + TYPE_VOLATILE not set, and TYPE_ARTIFICIALLY_VOLATILIZED not set. */ +static tree +objc_get_non_volatilized_type (tree type) +{ + tree t, non_volatilized_pointee = NULL_TREE; + + /* See if we already have the appropriate variant. */ + if (!TYPE_ARTIFICIALLY_VOLATILIZED (type)) + return type; + + /* At this point, we know that type is artificially volatilized, + hence it was created from an existing, + non-artificially-volatilized type. So we know that the search + will complete. */ + + /* If we have a pointer, find the non-volatilized type for the + pointee first. When we build a volatilized type, we volatilize + the pointee as well. */ + if (POINTER_TYPE_P (type)) + { + non_volatilized_pointee = objc_get_non_volatilized_type (TREE_TYPE (type)); - /* Only match up the types which were previously volatilized in similar fashion and not - because they were declared as such. */ - if (!lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (t))) + /* If there is none, something is wrong. */ + gcc_assert (non_volatilized_pointee); + } + + for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + { + /* We are looking for a non-volatile type. */ + if (TYPE_ARTIFICIALLY_VOLATILIZED (t)) continue; + if (!check_qualified_type + (t, type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE))) + continue; + + /* For pointer types, the pointees (and hence their + TYPE_LANG_SPECIFIC info, if any) must match up. */ + if (POINTER_TYPE_P (t)) + { + if (TREE_TYPE (t) != non_volatilized_pointee) + continue; + } + /* Everything matches up! */ return t; } + /* This should be impossible. */ + gcc_unreachable (); +} + +/* Build a type differing from TYPE only in that TYPE_VOLATILE is set. + Unlike tree.c:build_qualified_type(), preserve TYPE_LANG_SPECIFIC in the + process and mark the new type with TYPE_ARTIFICIALLY_VOLATILIZED. */ +static tree +objc_build_volatilized_type (tree type) +{ + tree t = objc_get_volatilized_type (type); + + if (t) + return t; + /* Ok, we could not re-use any of the pre-existing variants. Create a new one. */ t = build_variant_type_copy (type); TYPE_VOLATILE (t) = 1; - - TYPE_ATTRIBUTES (t) = merge_attributes (TYPE_ATTRIBUTES (type), - tree_cons (get_identifier ("objc_volatilized"), - NULL_TREE, - NULL_TREE)); + TYPE_ARTIFICIALLY_VOLATILIZED (t) = 1; + if (TREE_CODE (t) == ARRAY_TYPE) - TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (t)); + TREE_TYPE (t) = objc_build_volatilized_type (TREE_TYPE (type)); + + if (TYPE_HAS_OBJC_INFO (type)) + { + DUP_TYPE_OBJC_INFO (t, type); + TYPE_OBJC_INTERFACE (t) = TYPE_OBJC_INTERFACE (type); + TYPE_OBJC_PROTOCOL_LIST (t) = TYPE_OBJC_PROTOCOL_LIST (type); + } /* Set up the canonical type information. */ if (TYPE_STRUCTURAL_EQUALITY_P (type)) @@ -2703,10 +2789,10 @@ objc_type_quals_match (tree ltyp, tree r { int lquals = TYPE_QUALS (ltyp), rquals = TYPE_QUALS (rtyp); - if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (ltyp))) + if (TYPE_ARTIFICIALLY_VOLATILIZED (ltyp)) lquals &= ~TYPE_QUAL_VOLATILE; - if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (rtyp))) + if (TYPE_ARTIFICIALLY_VOLATILIZED (rtyp)) rquals &= ~TYPE_QUAL_VOLATILE; return (lquals == rquals); @@ -2831,14 +2917,14 @@ objc_check_global_decl (tree decl) error ("redeclaration of Objective-C class %qs", IDENTIFIER_POINTER (id)); } -/* Return a non-volatalized version of TYPE. */ - +/* Return a non-artificially-volatilized version of TYPE. This is the + reverse of objc_build_volatilized_type(); if the type is marked as + TYPE_ARTIFICIALLY_VOLATILIZED, it returns a variant without the + flag and which is not volatile. */ tree objc_non_volatilized_type (tree type) { - if (lookup_attribute ("objc_volatilized", TYPE_ATTRIBUTES (type))) - type = build_qualified_type (type, (TYPE_QUALS (type) & ~TYPE_QUAL_VOLATILE)); - return type; + return objc_get_non_volatilized_type (type); } /* Construct a PROTOCOLS-qualified variant of INTERFACE, where Index: gcc/objc/ChangeLog =================================================================== --- gcc/objc/ChangeLog (revision 167231) +++ gcc/objc/ChangeLog (working copy) @@ -1,5 +1,14 @@ 2010-11-29 Nicola Pero + * objc-act.c (objc_get_volatilized_type): New. + (objc_get_non_volatilized_type): New. + (objc_build_volatilized_type): Use objc_get_volatilized_type. + Duplicate ObjC type information when building the volatilized + type. Set TYPE_ARTIFICIALLY_VOLATILIZED for the new type. + (objc_non_volatilized_type): Use objc_get_non_volatilized_type. + +2010-11-29 Nicola Pero + * objc-act.c (objc_demangle): Return immediately if the string is too short. Detect names that do not need demangling, and return them unchanged. Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 167220) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,7 @@ +2010-11-28 Nicola Pero + + * tree.h (TYPE_ARTIFICIALLY_VOLATILIZED): New. + 2010-11-27 Jan Hubicka * dwarf2out.c (dwarf2out_begin_function): Set cold_text_section