From patchwork Wed Jul 21 03:09:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [C] Fix PR40563 Date: Tue, 20 Jul 2010 17:09:15 -0000 From: Shujing Zhao X-Patchwork-Id: 59400 Message-Id: <4C4664DB.6040902@oracle.com> To: GCC Patches Cc: "Joseph S. Myers" , Paolo Carlini Hi, This patch diagnose uninitialized const field in struct or union when -Wc++-compat enabled. Tested on i686-pc-linux-gnu with no regression. ok for trunk? /gcc 2010-07-21 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-21 Shujing Zhao PR c/40563 * gcc.dg/Wcxx-compat-20.c: New test 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. */ + +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++", + 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,16 @@ 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); + { + 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) + diagnose_uninitialized_cst_member (decl, type); + } } /* Given a parsed parameter declaration, decode it into a PARM_DECL. */ 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,7 @@ +/* { dg-do compile } */ +/* { dg-options "-Wc++-compat" } */ +typedef struct s { const int i; } s; /* { dg-message "should be initialized" } */ +void foo () { s v; } /* { dg-warning "uninitialized const member in" } */ + +union u {const int a; double b;}; /* { dg-message "should be initialized" } */ +void bar () { union u f; } /* { dg-warning "uninitialized const member in" } */