summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-17 08:25:20 +0000
committerpzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4>2010-08-17 08:25:20 +0000
commit980b024a34bd9f3d5040b1bc40fe5159727f13d5 (patch)
treeb2173160d60dbebd4e1f80ea7c24c0016432cdc3
parent8f3f9eab5083b3a78a92dfb3fae63f80039689a3 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/c-decl.c46
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/Wcxx-compat-20.c15
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" } */
+}