diff mbox series

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

Message ID 20190129182831.GR2135@tucnak
State New
Headers show
Series [C] Ignore compound literals in -W*misses-init warning (PR c/89061) | expand

Commit Message

Jakub Jelinek Jan. 29, 2019, 6:28 p.m. UTC
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.


	Jakub

Comments

Joseph Myers Jan. 29, 2019, 10:33 p.m. UTC | #1
On Tue, 29 Jan 2019, Jakub Jelinek wrote:

> 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?

OK.
diff mbox series

Patch

--- 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;
+}