OSDN Git Service

/gcc
authorpzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Aug 2010 08:25:20 +0000 (08:25 +0000)
committerpzhao <pzhao@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Aug 2010 08:25:20 +0000 (08:25 +0000)
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

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wcxx-compat-20.c [new file with mode: 0644]

index a01b1ae..e6f43ed 100644 (file)
@@ -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
index ec66692..5606df8 100644 (file)
@@ -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;
index 760b5f1..b312e3b 100644 (file)
@@ -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 (file)
index 0000000..af774ac
--- /dev/null
@@ -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" } */
+}