diff options
author | pzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-17 08:25:20 +0000 |
---|---|---|
committer | pzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-08-17 08:25:20 +0000 |
commit | 980b024a34bd9f3d5040b1bc40fe5159727f13d5 (patch) | |
tree | b2173160d60dbebd4e1f80ea7c24c0016432cdc3 | |
parent | 8f3f9eab5083b3a78a92dfb3fae63f80039689a3 (diff) | |
download | gcc-980b024a34bd9f3d5040b1bc40fe5159727f13d5.tar.gz |
/gcc
2010-08-17 Shujing Zhao <pearly.zhao@oracle.com>
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.
(finish_struct): Use strip_array_types.
/gcc/testsuite
2010-08-17 Shujing Zhao <pearly.zhao@oracle.com>
PR c/40563
* gcc.dg/Wcxx-compat-20.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@163296 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/c-decl.c | 46 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/Wcxx-compat-20.c | 15 |
4 files changed, 69 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a01b1ae5135..e6f43ed6d78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2010-08-17 Shujing Zhao <pearly.zhao@oracle.com> + + 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. + + (finish_struct): Use strip_array_types. + 2010-08-17 Jakub Jelinek <jakub@redhat.com> * function.c (block_fragments_nreverse, blocks_nreverse_all): New diff --git a/gcc/c-decl.c b/gcc/c-decl.c index ec6669219db..5606df82ec5 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -4103,6 +4103,35 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, 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_loc, tree 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. */ @@ -6872,9 +6908,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes, 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; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 760b5f1259f..b312e3b5a5b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-08-17 Shujing Zhao <pearly.zhao@oracle.com> + + PR c/40563 + * gcc.dg/Wcxx-compat-20.c: New test. + 2010-08-17 Daniel Kraft <d@domob.eu> PR fortran/38936 diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-20.c b/gcc/testsuite/gcc.dg/Wcxx-compat-20.c new file mode 100644 index 00000000000..af774acc818 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wcxx-compat-20.c @@ -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" } */ +} |