This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Patch for regressions 22013 and 22098


This patch fixes ICE-on-valid regressions 22013 and 22098 (plus
duplicate 22050) in the manner I suggested in
<http://gcc.gnu.org/ml/gcc-patches/2005-06/msg01463.html>: adding a
langhook used by recompute_tree_invarant_for_addr_expr to go from a
COMPOUND_LITERAL_EXPR to the decl within and removing special-case
code in build_unary_op which always treats the address of a compound
literal as TREE_INVARIANT and TREE_CONSTANT.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu, mainline
and 4.0 branch.  OK to commit to mainline?  OK for 4.0.2?

-- 
Joseph S. Myers               http://www.srcf.ucam.org/~jsm28/gcc/
    jsm@polyomino.org.uk (personal mail)
    joseph@codesourcery.com (CodeSourcery mail)
    jsm28@gcc.gnu.org (Bugzilla assignments and CCs)

2005-06-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/22013
	PR c/22098
	* langhooks.h (struct lang_hooks): Add expr_to_decl.
	* langhooks.c (lhd_expr_to_decl): New.
	* langhooks-def.h (lhd_expr_to_decl, LANG_HOOKS_EXPR_TO_DECL):
	New.
	(LANG_HOOKS_INITIALIZER): Update.
	* tree.c (recompute_tree_invarant_for_addr_expr): Call
	expr_to_decl langhook.
	* c-tree.h (c_expr_to_decl): Declare.
	* c-typeck.c (c_expr_to_decl): New.
	(build_unary_op): Do not handle ADDR_EXPR of COMPOUND_LITERAL_EXPR
	specially.
	* c-objc-common.h (LANG_HOOKS_EXPR_TO_DECL): Define.

testsuite:
2005-06-30  Joseph S. Myers  <joseph@codesourcery.com>

	PR c/22013
	PR c/22098
	* gcc.c-torture/compile/pr22013-1.c,
	gcc.c-torture/execute/pr22098-1.c,
	gcc.c-torture/execute/pr22098-2.c,
	gcc.c-torture/execute/pr22098-3.c: New tests.

diff -rupN GCC.orig/gcc/c-objc-common.h GCC/gcc/c-objc-common.h
--- GCC.orig/gcc/c-objc-common.h	2005-06-25 09:53:51.000000000 +0000
+++ GCC/gcc/c-objc-common.h	2005-06-30 11:00:17.000000000 +0000
@@ -117,6 +117,8 @@ extern void c_initialize_diagnostics (di
 #define LANG_HOOKS_REGISTER_BUILTIN_TYPE c_register_builtin_type
 #undef LANG_HOOKS_TO_TARGET_CHARSET
 #define LANG_HOOKS_TO_TARGET_CHARSET c_common_to_target_charset
+#undef LANG_HOOKS_EXPR_TO_DECL
+#define LANG_HOOKS_EXPR_TO_DECL c_expr_to_decl
 
 /* The C front end's scoping structure is very different from
    that expected by the language-independent code; it is best
diff -rupN GCC.orig/gcc/c-tree.h GCC/gcc/c-tree.h
--- GCC.orig/gcc/c-tree.h	2005-06-29 22:09:40.000000000 +0000
+++ GCC/gcc/c-tree.h	2005-06-30 11:01:08.000000000 +0000
@@ -573,6 +573,7 @@ extern tree c_finish_goto_label (tree);
 extern tree c_finish_goto_ptr (tree);
 extern void c_begin_vm_scope (unsigned int);
 extern void c_end_vm_scope (unsigned int);
+extern tree c_expr_to_decl (tree, bool *, bool *, bool *);
 
 /* Set to 0 at beginning of a function definition, set to 1 if
    a return statement that specifies a return value is seen.  */
diff -rupN GCC.orig/gcc/c-typeck.c GCC/gcc/c-typeck.c
--- GCC.orig/gcc/c-typeck.c	2005-06-29 22:09:40.000000000 +0000
+++ GCC/gcc/c-typeck.c	2005-06-30 11:12:18.000000000 +0000
@@ -2790,9 +2790,6 @@ build_unary_op (enum tree_code code, tre
 
       val = build1 (ADDR_EXPR, argtype, arg);
 
-      if (TREE_CODE (arg) == COMPOUND_LITERAL_EXPR)
-	TREE_INVARIANT (val) = TREE_CONSTANT (val) = 1;
-
       return val;
 
     default:
@@ -8142,3 +8139,24 @@ c_objc_common_truthvalue_conversion (tre
      leaving those to give errors later?  */
   return c_common_truthvalue_conversion (expr);
 }
+
+
+/* Convert EXPR to a contained DECL, updating *TC, *TI and *SE as
+   required.  */
+
+tree
+c_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
+		bool *ti ATTRIBUTE_UNUSED, bool *se)
+{
+  if (TREE_CODE (expr) == COMPOUND_LITERAL_EXPR)
+    {
+      tree decl = COMPOUND_LITERAL_EXPR_DECL (expr);
+      /* Executing a compound literal inside a function reinitializes
+	 it.  */
+      if (!TREE_STATIC (decl))
+	*se = true;
+      return decl;
+    }
+  else
+    return expr;
+}
diff -rupN GCC.orig/gcc/langhooks-def.h GCC/gcc/langhooks-def.h
--- GCC.orig/gcc/langhooks-def.h	2005-06-25 09:54:00.000000000 +0000
+++ GCC/gcc/langhooks-def.h	2005-06-30 10:56:31.000000000 +0000
@@ -69,6 +69,7 @@ extern const char *lhd_comdat_group (tre
 extern tree lhd_expr_size (tree);
 extern size_t lhd_tree_size (enum tree_code);
 extern HOST_WIDE_INT lhd_to_target_charset (HOST_WIDE_INT);
+extern tree lhd_expr_to_decl (tree, bool *, bool *, bool *);
 
 /* Declarations of default tree inlining hooks.  */
 extern tree lhd_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
@@ -123,6 +124,7 @@ extern int lhd_gimplify_expr (tree *, tr
 #define LANG_HOOKS_TREE_SIZE		lhd_tree_size
 #define LANG_HOOKS_TYPES_COMPATIBLE_P	lhd_types_compatible_p
 #define LANG_HOOKS_BUILTIN_FUNCTION	builtin_function
+#define LANG_HOOKS_EXPR_TO_DECL		lhd_expr_to_decl
 #define LANG_HOOKS_TO_TARGET_CHARSET	lhd_to_target_charset
 
 #define LANG_HOOKS_FUNCTION_INIT	lhd_do_nothing_f
@@ -299,6 +301,7 @@ extern tree lhd_make_node (enum tree_cod
   LANG_HOOKS_GIMPLIFY_EXPR, \
   LANG_HOOKS_FOLD_OBJ_TYPE_REF, \
   LANG_HOOKS_BUILTIN_FUNCTION, \
+  LANG_HOOKS_EXPR_TO_DECL, \
 }
 
 #endif /* GCC_LANG_HOOKS_DEF_H */
diff -rupN GCC.orig/gcc/langhooks.c GCC/gcc/langhooks.c
--- GCC.orig/gcc/langhooks.c	2005-06-25 09:54:00.000000000 +0000
+++ GCC/gcc/langhooks.c	2005-06-30 10:58:03.000000000 +0000
@@ -543,3 +543,10 @@ lhd_to_target_charset (HOST_WIDE_INT c)
 {
   return c;
 }
+
+tree
+lhd_expr_to_decl (tree expr, bool *tc ATTRIBUTE_UNUSED,
+		  bool *ti ATTRIBUTE_UNUSED, bool *se ATTRIBUTE_UNUSED)
+{
+  return expr;
+}
diff -rupN GCC.orig/gcc/langhooks.h GCC/gcc/langhooks.h
--- GCC.orig/gcc/langhooks.h	2005-06-25 09:54:00.000000000 +0000
+++ GCC/gcc/langhooks.h	2005-06-30 10:54:16.000000000 +0000
@@ -412,6 +412,12 @@ struct lang_hooks
 			    enum built_in_class bt_class,
 			    const char *library_name, tree attrs);
 
+  /* Called by recompute_tree_invarant_for_addr_expr to go from EXPR
+     to a contained expression or DECL, possibly updating *TC, *TI or
+     *SE if in the process TREE_CONSTANT, TREE_INVARIANT or
+     TREE_SIDE_EFFECTS need updating.  */
+  tree (*expr_to_decl) (tree expr, bool *tc, bool *ti, bool *se);
+
   /* Whenever you add entries here, make sure you adjust langhooks-def.h
      and langhooks.c accordingly.  */
 };
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr22013-1.c GCC/gcc/testsuite/gcc.c-torture/compile/pr22013-1.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/compile/pr22013-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/compile/pr22013-1.c	2005-06-30 09:42:32.000000000 +0000
@@ -0,0 +1,11 @@
+typedef unsigned short W;
+typedef const W *P;
+
+extern void g(P);
+
+void
+f ()
+{
+  const P s = (const W []){ 'R' };
+  g (s);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-1.c GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-1.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-1.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-1.c	2005-06-30 09:39:07.000000000 +0000
@@ -0,0 +1,14 @@
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int
+main (void)
+{
+  int a = 0;
+  int *p;
+  size_t b;
+  b = (size_t)(p = &(int []){0, 1, 2}[++a]);
+  if (a != 1 || *p != 1 || *(int *)b != 1)
+    abort ();
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-2.c GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-2.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-2.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-2.c	2005-06-30 09:39:14.000000000 +0000
@@ -0,0 +1,14 @@
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int
+main (void)
+{
+  int a = 0;
+  int *p;
+  size_t b;
+  b = (size_t)(p = &(int []){0, 1, 2}[1]);
+  if (*p != 1 || *(int *)b != 1)
+    abort ();
+  exit (0);
+}
diff -rupN GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-3.c GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-3.c
--- GCC.orig/gcc/testsuite/gcc.c-torture/execute/pr22098-3.c	1970-01-01 00:00:00.000000000 +0000
+++ GCC/gcc/testsuite/gcc.c-torture/execute/pr22098-3.c	2005-06-30 09:46:07.000000000 +0000
@@ -0,0 +1,16 @@
+extern void abort (void);
+extern void exit (int);
+typedef __SIZE_TYPE__ size_t;
+int n = 0;
+int f (void) { return ++n; }
+int
+main (void)
+{
+  int a = 0;
+  int *p;
+  size_t b;
+  b = (size_t)(p = &(int []){0, f(), 2}[1]);
+  if (*p != 1 || *(int *)b != 1 || n != 1)
+    abort ();
+  exit (0);
+}
diff -rupN GCC.orig/gcc/tree.c GCC/gcc/tree.c
--- GCC.orig/gcc/tree.c	2005-06-29 22:09:17.000000000 +0000
+++ GCC/gcc/tree.c	2005-06-30 10:59:25.000000000 +0000
@@ -2466,6 +2466,8 @@ do { tree _node = (NODE); \
 	UPDATE_TITCSE (TREE_OPERAND (node, 2));
     }
 
+  node = lang_hooks.expr_to_decl (node, &tc, &ti, &se);
+
   /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
      the address, since &(*a)->b is a form of addition.  If it's a decl, it's
      invariant and constant if the decl is static.  It's also invariant if it's


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]