[C PATCH] Ignore compound literals in -W*misses-init warning (PR c/89061)

Jakub Jelinek jakub@redhat.com
Tue Jan 29 18:31:00 GMT 2019


Hi!

While gotos across automatic compound literal initialization do
cross their initialization, I can't think of any way how could code after
the label to which the goto bypasses it get access to the uninitialized
compound literal.  Even if the complit address is taken, it can be assigned
to some variable only if it is not bypassed by the goto, otherwise there
should be no way to refer to it.

So, the following patch disables the warning for compound literals.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2019-01-29  Jakub Jelinek  <jakub@redhat.com>

	PR c/89061
	* c-tree.h (C_DECL_COMPOUND_LITERAL_P): Define.
	* c-decl.c (decl_jump_unsafe): Return false for
	C_DECL_COMPOUND_LITERAL_P decls.
	(build_compound_literal): Set C_DECL_COMPOUND_LITERAL_P.

	* gcc.dg/pr89061.c: New test.

--- gcc/c/c-tree.h.jj	2019-01-01 12:37:48.637458450 +0100
+++ gcc/c/c-tree.h	2019-01-29 16:14:25.310950693 +0100
@@ -96,6 +96,10 @@ along with GCC; see the file COPYING3.
    #pragma omp threadprivate.  */
 #define C_DECL_THREADPRIVATE_P(DECL) DECL_LANG_FLAG_3 (VAR_DECL_CHECK (DECL))
 
+/* Set on VAR_DECLs for compound literals.  */
+#define C_DECL_COMPOUND_LITERAL_P(DECL) \
+  DECL_LANG_FLAG_5 (VAR_DECL_CHECK (DECL))
+
 /* Nonzero for a decl which either doesn't exist or isn't a prototype.
    N.B. Could be simplified if all built-in decls had complete prototypes
    (but this is presently difficult because some of them need FILE*).  */
--- gcc/c/c-decl.c.jj	2019-01-29 00:48:57.361683401 +0100
+++ gcc/c/c-decl.c	2019-01-29 16:12:54.383444385 +0100
@@ -659,6 +659,14 @@ decl_jump_unsafe (tree decl)
   if (error_operand_p (decl))
     return false;
 
+  /* Don't warn for compound literals.  If a goto statement crosses
+     their initialization, it should cross also all the places where
+     the complit is used or where the complit address might be saved
+     into some variable, so code after the label to which goto jumps
+     should not be able to refer to the compound literal.  */
+  if (VAR_P (decl) && C_DECL_COMPOUND_LITERAL_P (decl))
+    return false;
+
   /* Always warn about crossing variably modified types.  */
   if ((VAR_P (decl) || TREE_CODE (decl) == TYPE_DECL)
       && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
@@ -5486,6 +5494,7 @@ build_compound_literal (location_t loc,
   DECL_READ_P (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
   DECL_IGNORED_P (decl) = 1;
+  C_DECL_COMPOUND_LITERAL_P (decl) = 1;
   TREE_TYPE (decl) = type;
   c_apply_type_quals_to_decl (TYPE_QUALS (strip_array_types (type)), decl);
   if (alignas_align)
--- gcc/testsuite/gcc.dg/pr89061.c.jj	2019-01-29 16:15:22.220015753 +0100
+++ gcc/testsuite/gcc.dg/pr89061.c	2019-01-29 16:08:50.862444669 +0100
@@ -0,0 +1,27 @@
+/* PR c/89061 */
+/* { dg-do compile } */
+/* { dg-options "-Wjump-misses-init" } */
+
+struct S { int s; };
+
+int
+foo (int x)
+{
+  struct S s = { 0 };
+  if ((s.s = x) == 0)
+    goto cleanup;		/* { dg-bogus "jump skips variable initialization" } */
+  s = (struct S) { .s = 42 };
+ cleanup:
+  return s.s;
+}
+
+int
+bar (int x)
+{
+  struct S *s = &(struct S) { 0 };
+  if ((s->s = x) == 0)
+    goto cleanup;		/* { dg-bogus "jump skips variable initialization" } */
+  s = &(struct S) { .s = 42 };
+ cleanup:
+  return s->s;
+}

	Jakub



More information about the Gcc-patches mailing list