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]

RFA: Fix PR 28139


:ADDPATCH c++:

By creating the temporary variable with the proper type, we get the right alias sets so that
scheduling won't move the load from the temporary variable before its initialization.


As an added bonus, the optimizers can eliminate INDIRECT_REF/ ADDR_PAIRS
if they are not spearated by a type conversion, thus allowing the temporary variable to be eliminated.


Regression tested on i686-pc-linux-gnu native and X sh-elf.
2006-06-22  J"orn Rennecke <joern.rennecke@st.com>

	cp:
	PR c++/28139
	* except.c (expand_start_catch_block): Use correct types for bitwise
	copy.
	testsuite:
	PR c++/28139
	* g++.dg/eh/alias1.C: New test.

Index: cp/except.c
===================================================================
/usr/bin/diff -p -d -F^( -u -L cp/except.c	(revision 114810) -L cp/except.c	(working copy) cp/.svn/text-base/except.c.svn-base cp/except.c
--- cp/except.c	(revision 114810)
+++ cp/except.c	(working copy)
@@ -458,7 +458,14 @@ expand_start_catch_block (tree decl)
   else
     {
       tree init = do_begin_catch ();
-      exp = create_temporary_var (ptr_type_node);
+      tree init_type = type;
+
+      /* Pointers are passed by values, everything else by reference.  */
+      if (!TYPE_PTR_P (type))
+	init_type = build_pointer_type (type);
+      if (init_type != TREE_TYPE (init))
+	init = build1 (NOP_EXPR, init_type, init);
+      exp = create_temporary_var (init_type);
       DECL_REGISTER (exp) = 1;
       cp_finish_decl (exp, init, /*init_const_expr=*/false,
 		      NULL_TREE, LOOKUP_ONLYCONVERTING);
Index: testsuite/g++.dg/eh/alias1.C
===================================================================
/usr/bin/diff -p -d -F^( -u -L testsuite/g++.dg/eh/alias1.C	(revision 0) -L testsuite/g++.dg/eh/alias1.C	(revision 0) testsuite/g++.dg/eh/.svn/empty-file testsuite/g++.dg/eh/alias1.C
--- testsuite/g++.dg/eh/alias1.C	(revision 0)
+++ testsuite/g++.dg/eh/alias1.C	(revision 0)
@@ -0,0 +1,42 @@
+// { dg-do run }
+// { dg-options "-O3" }
+/* PR c++/28139: disjoint alias sets for the store from
+   expand_start_catch_block than for loading P result in P being loaded
+   before it is initialized for sh-elf.  */
+
+extern "C" {
+void exit (int) __attribute__ ((noreturn));
+}
+
+int i_glob = 42;
+int *p0 = &i_glob;
+typedef int **ipp;
+
+void
+g (int i)
+{
+  if (!i_glob)
+    exit ((int)(long long) &i);
+}
+
+static void
+h ()
+{
+  throw &p0;
+}
+
+int
+main()
+{
+  g (42);
+  try
+    {
+     h ();
+    }
+  catch (const ipp &p)
+    {
+      if (**p != 42)
+	exit (1);
+    }
+  return 0;
+}

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