From patchwork Fri Jul 30 09:58:19 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Shujing Zhao X-Patchwork-Id: 60344 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 EA8B2B70D0 for ; Fri, 30 Jul 2010 20:01:07 +1000 (EST) Received: (qmail 3731 invoked by alias); 30 Jul 2010 10:01:04 -0000 Received: (qmail 3510 invoked by uid 22791); 30 Jul 2010 10:01:03 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Received: from rcsinet10.oracle.com (HELO rcsinet10.oracle.com) (148.87.113.121) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 30 Jul 2010 10:00:58 +0000 Received: from rcsinet13.oracle.com (rcsinet13.oracle.com [148.87.113.125]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.2) with ESMTP id o6UA0mKj000559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 30 Jul 2010 10:00:49 GMT Received: from acsmt353.oracle.com (acsmt353.oracle.com [141.146.40.153]) by rcsinet13.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o6U9G80i032371; Fri, 30 Jul 2010 10:00:46 GMT Received: from abhmt019.oracle.com by acsmt354.oracle.com with ESMTP id 470694141280483971; Fri, 30 Jul 2010 02:59:31 -0700 Received: from dhcp-beijing-cdc-10-182-121-28.cn.oracle.com (/10.182.121.28) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 30 Jul 2010 02:59:30 -0700 Message-ID: <4C52A23B.6010408@oracle.com> Date: Fri, 30 Jul 2010 17:58:19 +0800 From: Shujing Zhao User-Agent: Thunderbird 2.0.0.24 (X11/20100228) MIME-Version: 1.0 To: =?ISO-8859-1?Q?Fabien_Ch=EAne?= CC: "Joseph S. Myers" , GCC Patches , Paolo Carlini Subject: Re: [PATCH, C] Fix PR40563 References: <4C4664DB.6040902@oracle.com> <4C4FEC69.3090600@oracle.com> In-Reply-To: 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 On 07/28/2010 09:15 PM, Fabien ChĂȘne wrote: > 2010/7/28 Shujing Zhao : >> On 07/27/2010 09:58 PM, Joseph S. Myers wrote: >>> On Wed, 21 Jul 2010, Shujing Zhao wrote: >>> >>>> Index: c-decl.c >>>> =================================================================== >>>> --- c-decl.c (revision 162361) >>>> +++ c-decl.c (working copy) >>>> @@ -4103,6 +4103,35 @@ start_decl (struct c_declarator *declara >>>> return tem; >>>> } >>>> +/* Subroutine of finish_decl. Diagnose uninitialized const member of >>>> type TYPE. >>>> + DECL is the original declaration. */ >>> This comment is unclear. What you seem to mean is: TYPE is the type of an >>> uninitialized object DECL. If that object has a const member, diagnose >>> this. >>> >> Thanks. >>> Why do you need to recurse down among fields? Why isn't checking >>> C_TYPE_FIELDS_READONLY enough? >>> >> It used to notice which field should be initialized, just like the >> diagnostics at c++. If the notice is not very necessary, >> C_TYPE_FIELDS_READONLY is enough. >> >>> What if the original uninitialized object is not a structure but an array >>> of structures? Will you diagnose things in that case? >> C++ would not error an uninitialized array of structure that has a const >> member. So I think it doesn't need warn at C? > > It seems to be PR c++/43719, which should be fixed on mainline. > OK. Clear the comment of diagnose_uninitialized_cst_member. C_TYPE_FIELDS_READONLY is used before recursing the struct or union. Uninitialized array of structures would be diagnosed if one of members is const. The warned type is changed to "strip_array_types (TREE_TYPE (decl)", so that it would warn struct or union type, not the array. The testcase is fixed to test the recursing and test the array of structure that has const member. Tested on trunk and bootstraped. Is it ok? Pearly /gcc 2010-07-30 Shujing Zhao PR c/40563 * c-decl.c (diagnose_uninitialized_cst_member): New function. (finish_decl): Use it to issue a -Wc++-compat warning about uninitialized const field in struct or union. /gcc/testsuite 2010-07-30 Shujing Zhao PR c/40563 * gcc.dg/Wcxx-compat-20.c: New test Index: c-decl.c =================================================================== --- c-decl.c (revision 162706) +++ c-decl.c (working copy) @@ -4103,6 +4103,35 @@ start_decl (struct c_declarator *declara return tem; } +/* Subroutine of finish_decl. TYPE is the type of an uninitialized object + DECL or the non-array element type if DECL is an uninitialized array. + If that type has a const member, diagnose this. */ + +static void +diagnose_uninitialized_cst_member (tree decl, tree type) +{ + tree field; + for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + { + tree field_type; + if (TREE_CODE (field) != FIELD_DECL) + continue; + field_type = strip_array_types (TREE_TYPE (field)); + + if (TYPE_QUALS (field_type) & TYPE_QUAL_CONST) + { + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, + "uninitialized const member in %qT is invalid in C++", + strip_array_types (TREE_TYPE (decl))); + inform (DECL_SOURCE_LOCATION (field), "%qD should be initialized", field); + } + + if (TREE_CODE (field_type) == RECORD_TYPE + || TREE_CODE (field_type) == UNION_TYPE) + diagnose_uninitialized_cst_member (decl, field_type); + } +} + /* Finish processing of a declaration; install its initial value. If ORIGTYPE is not NULL_TREE, it is the original type of INIT. @@ -4420,11 +4449,18 @@ finish_decl (tree decl, location_t init_ if (warn_cxx_compat && TREE_CODE (decl) == VAR_DECL - && TREE_READONLY (decl) && !DECL_EXTERNAL (decl) && DECL_INITIAL (decl) == NULL_TREE) - warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, - "uninitialized const %qD is invalid in C++", decl); + { + type = strip_array_types (type); + if (TREE_READONLY (decl)) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat, + "uninitialized const %qD is invalid in C++", decl); + else if ((TREE_CODE (type) == RECORD_TYPE + || TREE_CODE (type) == UNION_TYPE) + && C_TYPE_FIELDS_READONLY (type)) + diagnose_uninitialized_cst_member (decl, type); + } } /* Given a parsed parameter declaration, decode it into a PARM_DECL. */ @@ -6859,9 +6895,7 @@ finish_struct (location_t loc, tree t, t else { /* A field that is pseudo-const makes the structure likewise. */ - tree t1 = TREE_TYPE (x); - while (TREE_CODE (t1) == ARRAY_TYPE) - t1 = TREE_TYPE (t1); + tree t1 = strip_array_types (TREE_TYPE (x)); if ((TREE_CODE (t1) == RECORD_TYPE || TREE_CODE (t1) == UNION_TYPE) && C_TYPE_FIELDS_READONLY (t1)) C_TYPE_FIELDS_READONLY (t) = 1; Index: testsuite/gcc.dg/Wcxx-compat-20.c =================================================================== --- testsuite/gcc.dg/Wcxx-compat-20.c (revision 0) +++ testsuite/gcc.dg/Wcxx-compat-20.c (revision 0) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-Wc++-compat" } */ +typedef struct s { const int i; } s; /* { dg-message "should be initialized" } */ +union u {const int a; double b;}; /* { dg-message "should be initialized" } */ +struct ts { int a; s v;}; +struct ta { int a; s v[2];}; + +void f () +{ + s v1; /* { dg-warning "uninitialized const member in" } */ + s va[2]; /* { dg-warning "uninitialized const member in" } */ + union u v2; /* { dg-warning "uninitialized const member in" } */ + struct ts v3; /* { dg-warning "uninitialized const member in" } */ + struct ta ta[2]; /* { dg-warning "uninitialized const member in" } */ +}