diff mbox

Backports to 4.8 branch

Message ID 20140306081841.GA22862@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 6, 2014, 8:18 a.m. UTC
Hi!

I've backported a few bugfixes to 4.8 branch, bootstrapped/regtested on
x86_64-linux and i686-linux, committed to branch.

	Jakub
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/60400
	Backport from mainline
	2013-06-24  Dehao Chen  <dehao@google.com>

	* files.c (_cpp_stack_include): Fix the highest_location when header
	file is guarded by #ifndef and is included twice.

	2014-03-03  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/60400
	* c-c++-common/cpp/pr60400.c: New test.
	* c-c++-common/cpp/pr60400-1.h: New file.
	* c-c++-common/cpp/pr60400-2.h: New file.
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-05  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/57499
	* tree-eh.c (cleanup_empty_eh): Bail out on totally empty
	bb with no successors.

	* g++.dg/torture/pr57499.C: New test.

--- gcc/tree-eh.c	(revision 207503)
+++ gcc/tree-eh.c	(revision 207504)
@@ -4396,8 +4396,11 @@ cleanup_empty_eh (eh_landing_pad lp)
   /* If the block is totally empty, look for more unsplitting cases.  */
   if (gsi_end_p (gsi))
     {
-      /* For the degenerate case of an infinite loop bail out.  */
-      if (infinite_empty_loop_p (e_out))
+      /* For the degenerate case of an infinite loop bail out.
+	 If bb has no successors and is totally empty, which can happen e.g.
+	 because of incorrect noreturn attribute, bail out too.  */
+      if (e_out == NULL
+	  || infinite_empty_loop_p (e_out))
 	return ret;
 
       return ret | cleanup_empty_eh_unsplit (bb, e_out, lp);
--- gcc/testsuite/g++.dg/torture/pr57499.C	(revision 0)
+++ gcc/testsuite/g++.dg/torture/pr57499.C	(revision 207504)
@@ -0,0 +1,14 @@
+// PR middle-end/57499
+// { dg-do compile }
+
+struct S
+{
+  ~S () __attribute__ ((noreturn)) {} // { dg-warning "function does return" }
+};
+
+void
+foo ()
+{
+  S s;
+  throw 1;
+}
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-07  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/56824
	* line-map.c (linemap_compare_locations): Look through adhoc locations
	for both l0 and l1.

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

--- libcpp/line-map.c	(revision 207605)
+++ libcpp/line-map.c	(revision 207606)
@@ -1024,6 +1024,11 @@ linemap_compare_locations (struct line_m
   bool pre_virtual_p, post_virtual_p;
   source_location l0 = pre, l1 = post;
 
+  if (IS_ADHOC_LOC (l0))
+    l0 = set->location_adhoc_data_map.data[l0 & MAX_SOURCE_LOCATION].locus;
+  if (IS_ADHOC_LOC (l1))
+    l1 = set->location_adhoc_data_map.data[l1 & MAX_SOURCE_LOCATION].locus;
+
   if (l0 == l1)
     return 0;
 
--- gcc/testsuite/gcc.dg/pr56824.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr56824.c	(revision 207606)
@@ -0,0 +1,18 @@
+/* PR preprocessor/56824 */
+/* { dg-do compile } */
+/* { dg-options "-Waggregate-return" } */
+
+struct S { int i; };
+struct S foo (void);
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waggregate-return"
+
+int
+main ()
+{
+  foo ();
+  return 0;
+}
+
+#pragma GCC diagnostic pop
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-11  Richard Henderson  <rth@redhat.com>
		    Jakub Jelinek  <jakub@redhat.com>

	PR debug/59776
	* tree-sra.c (load_assign_lhs_subreplacements): Add VIEW_CONVERT_EXPR
	around drhs if type conversion to lacc->type is not useless.

	* gcc.dg/guality/pr59776.c: New test.

--- gcc/tree-sra.c	(revision 207694)
+++ gcc/tree-sra.c	(revision 207695)
@@ -2950,6 +2950,10 @@ load_assign_lhs_subreplacements (struct
 						  lacc);
 	      else
 		drhs = NULL_TREE;
+	      if (drhs
+		  && !useless_type_conversion_p (lacc->type, TREE_TYPE (drhs)))
+		drhs = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
+					lacc->type, drhs);
 	      ds = gimple_build_debug_bind (get_access_replacement (lacc),
 					    drhs, gsi_stmt (*old_gsi));
 	      gsi_insert_after (new_gsi, ds, GSI_NEW_STMT);
--- gcc/testsuite/gcc.dg/guality/pr59776.c	(revision 0)
+++ gcc/testsuite/gcc.dg/guality/pr59776.c	(revision 207695)
@@ -0,0 +1,29 @@
+/* PR debug/59776 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../nop.h"
+
+struct S { float f, g; };
+
+__attribute__((noinline, noclone)) void
+foo (struct S *p)
+{
+  struct S s1, s2;			/* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" } } */
+  s1 = *p;				/* { dg-final { gdb-test pr59776.c:17 "s1.g" "6.0" } } */
+  s2 = s1;				/* { dg-final { gdb-test pr59776.c:17 "s2.f" "0.0" } } */
+  *(int *) &s2.f = 0;			/* { dg-final { gdb-test pr59776.c:17 "s2.g" "6.0" } } */
+  asm volatile (NOP : : : "memory");	/* { dg-final { gdb-test pr59776.c:20 "s1.f" "5.0" } } */
+  asm volatile (NOP : : : "memory");	/* { dg-final { gdb-test pr59776.c:20 "s1.g" "6.0" } } */
+  s2 = s1;				/* { dg-final { gdb-test pr59776.c:20 "s2.f" "5.0" } } */
+  asm volatile (NOP : : : "memory");	/* { dg-final { gdb-test pr59776.c:20 "s2.g" "6.0" } } */
+  asm volatile (NOP : : : "memory");
+}
+
+int
+main ()
+{
+  struct S x = { 5.0f, 6.0f };
+  foo (&x);
+  return 0;
+}
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-11  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/52370
	* trans-decl.c (gfc_build_dummy_array_decl): Set TREE_NO_WARNING
	on decl if sym->attr.optional.

	* gfortran.dg/pr52370.f90: New test.

--- gcc/fortran/trans-decl.c	(revision 207697)
+++ gcc/fortran/trans-decl.c	(revision 207698)
@@ -1014,6 +1014,10 @@ gfc_build_dummy_array_decl (gfc_symbol *
   TREE_STATIC (decl) = 0;
   DECL_EXTERNAL (decl) = 0;
 
+  /* Avoid uninitialized warnings for optional dummy arguments.  */
+  if (sym->attr.optional)
+    TREE_NO_WARNING (decl) = 1;
+
   /* We should never get deferred shape arrays here.  We used to because of
      frontend bugs.  */
   gcc_assert (sym->as->type != AS_DEFERRED);
--- gcc/testsuite/gfortran.dg/pr52370.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/pr52370.f90	(revision 207698)
@@ -0,0 +1,21 @@
+! PR fortran/52370
+! { dg-do compile }
+! { dg-options "-O1 -Wall" }
+
+module pr52370
+contains
+  subroutine foo(a,b)
+    real, intent(out) :: a
+    real, dimension(:), optional, intent(out) :: b
+    a=0.5
+    if (present(b)) then
+      b=1.0
+    end if
+  end subroutine foo
+end module pr52370
+
+program prg52370
+  use pr52370
+  real :: a
+  call foo(a)
+end program prg52370
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-12  Jakub Jelinek  <jakub@redhat.com>

	PR c/60101
	* c-common.c (merge_tlist): If copy is true, call new_tlist,
	if false, add ADD itself, rather than vice versa.
	(verify_tree): For COND_EXPR, don't call merge_tlist with non-zero
	copy.  For SAVE_EXPR, only call merge_tlist once.

	* c-c++-common/pr60101.c: New test.

--- gcc/c-family/c-common.c	(revision 207710)
+++ gcc/c-family/c-common.c	(revision 207711)
@@ -2976,7 +2976,7 @@ merge_tlist (struct tlist **to, struct t
 	  }
       if (!found)
 	{
-	  *end = copy ? add : new_tlist (NULL, add->expr, add->writer);
+	  *end = copy ? new_tlist (NULL, add->expr, add->writer) : add;
 	  end = &(*end)->next;
 	  *end = 0;
 	}
@@ -3134,7 +3134,7 @@ verify_tree (tree x, struct tlist **pbef
       verify_tree (TREE_OPERAND (x, 0), &tmp_before, &tmp_list2, NULL_TREE);
       warn_for_collisions (tmp_list2);
       merge_tlist (pbefore_sp, tmp_before, 0);
-      merge_tlist (pbefore_sp, tmp_list2, 1);
+      merge_tlist (pbefore_sp, tmp_list2, 0);
 
       tmp_list3 = tmp_nosp = 0;
       verify_tree (TREE_OPERAND (x, 1), &tmp_list3, &tmp_nosp, NULL_TREE);
@@ -3238,12 +3238,7 @@ verify_tree (tree x, struct tlist **pbef
 	    warn_for_collisions (tmp_nosp);
 
 	    tmp_list3 = 0;
-	    while (tmp_nosp)
-	      {
-		struct tlist *t = tmp_nosp;
-		tmp_nosp = t->next;
-		merge_tlist (&tmp_list3, t, 0);
-	      }
+	    merge_tlist (&tmp_list3, tmp_nosp, 0);
 	    t->cache_before_sp = tmp_before;
 	    t->cache_after_sp = tmp_list3;
 	  }
--- gcc/testsuite/c-c++-common/pr60101.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr60101.c	(revision 207711)
@@ -0,0 +1,112 @@
+/* PR c/60101 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+extern int *a, b, *c, *d;
+
+void
+foo (double _Complex *x, double _Complex *y, double _Complex *z, unsigned int l, int w)
+{
+  unsigned int e = (unsigned int) a[3];
+  double _Complex (*v)[l][4][e][l][4] = (double _Complex (*)[l][4][e][l][4]) z;
+  double _Complex (*f)[l][b][l] = (double _Complex (*)[l][b][l]) y;
+  unsigned int g = c[0] * c[1] * c[2];
+  unsigned int h = d[0] + c[0] * (d[1] + c[1] * d[2]);
+  unsigned int i;
+
+  for (i = 0; i < e; i++)
+    {
+      int j = e * d[3] + i;
+
+      unsigned int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11;
+      float _Complex s = 0.;
+      unsigned int t = 0;
+
+      for (n0 = 0; n0 < l; n0++)
+	for (n1 = 0; n1 < l; n1++)
+	  for (n2 = 0; n2 < l; n2++)
+	    for (n3 = 0; n3 < l; n3++)
+	      for (n4 = 0; n4 < l; n4++)
+		for (n5 = 0; n5 < l; n5++)
+		  for (n6 = 0; n6 < l; n6++)
+		    for (n7 = 0; n7 < l; n7++)
+		      for (n8 = 0; n8 < l; n8++)
+			for (n9 = 0; n9 < l; n9++)
+			  for (n10 = 0; n10 < l; n10++)
+			    for (n11 = 0; n11 < l; n11++)
+			      {
+				if (t % g == h)
+				  s
+				    += f[n0][n4][j][n8] * f[n1][n5][j][n9] * ~(f[n2][n6][w][n10]) * ~(f[n3][n7][w][n11])
+				       * (+0.25 * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.25 * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  - 0.5 * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.25 * v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  - 0.5 * v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  + 0.25 * v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.25 * v[0][n3][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  - 0.5 * v[0][n3][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  + 0.25 * v[0][n3][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n10][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.25 * v[0][n3][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  + 0.25 * v[0][n3][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  - 0.5 * v[0][n3][0][i][n9][1] * v[0][n10][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.25 * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  + 0.25 * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 1. * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n2][0][i][n5][1] * v[0][n3][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  + 0.25 * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n6][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  + 0.25 * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n11][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  - 0.5 * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n6][1][i][n1][0] * v[0][n7][1][i][n0][0]
+					  + 1. * v[0][n10][0][i][n9][1] * v[0][n3][0][i][n5][1] * v[0][n2][0][i][n4][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n6][1][i][n0][0]
+					  + 0.5 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0] * v[0][n10][0][i][n8][0]
+					  - 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n11][1][i][n1][0] * v[0][n7][1][i][n0][0] * v[0][n10][0][i][n8][0]
+					  - 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n0][0] * v[0][n10][0][i][n1][0]
+					  + 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n1][0] * v[0][n10][0][i][n0][0]
+					  + 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n0][0] * v[0][n10][0][i][n1][0]
+					  - 0.5 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n3][0][i][n5][1]
+					  * v[0][n11][1][i][n8][0] * v[0][n7][1][i][n1][0] * v[0][n10][0][i][n0][0]
+					  - 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1]
+					  * v[0][n7][1][i][n1][0] * v[0][n11][1][i][n0][0] * v[0][n3][0][i][n8][0]
+					  - 0.25 * v[0][n6][1][i][n4][1] * v[0][n2][0][i][n9][1] * v[0][n10][0][i][n5][1]
+					  * v[0][n7][1][i][n8][0] * v[0][n11][1][i][n0][0] * v[0][n3][0][i][n1][0]);
+				t++;
+			      }
+      int u = (j - w + b) % b;
+      int q = (j >= w ? +1 : -1);
+      int r = q;
+      x[u] += r * s;
+    }
+}
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-13  Jakub Jelinek  <jakub@redhat.com>

	PR target/43546
	* expr.c (compress_float_constant): If x is a hard register,
	extend into a pseudo and then move to x.

	* gcc.target/i386/pr43546.c: New test.

--- gcc/expr.c	(revision 207756)
+++ gcc/expr.c	(revision 207757)
@@ -3726,12 +3726,21 @@ compress_float_constant (rtx x, rtx y)
 	 into a new pseudo.  This constant may be used in different modes,
 	 and if not, combine will put things back together for us.  */
       trunc_y = force_reg (srcmode, trunc_y);
-      emit_unop_insn (ic, x, trunc_y, UNKNOWN);
+
+      /* If x is a hard register, perform the extension into a pseudo,
+	 so that e.g. stack realignment code is aware of it.  */
+      rtx target = x;
+      if (REG_P (x) && HARD_REGISTER_P (x))
+	target = gen_reg_rtx (dstmode);
+
+      emit_unop_insn (ic, target, trunc_y, UNKNOWN);
       last_insn = get_last_insn ();
 
-      if (REG_P (x))
+      if (REG_P (target))
 	set_unique_reg_note (last_insn, REG_EQUAL, y);
 
+      if (target != x)
+	return emit_move_insn (x, target);
       return last_insn;
     }
 
--- gcc/testsuite/gcc.target/i386/pr43546.c	(revision 0)
+++ gcc/testsuite/gcc.target/i386/pr43546.c	(revision 207757)
@@ -0,0 +1,12 @@
+/* PR target/43546 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-additional-options "-mpreferred-stack-boundary=2 -msseregparm -msse" { target ia32 } } */
+
+extern void bar (double);
+
+void
+foo (void)
+{
+  bar (1.0);
+}
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-19  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/58844
	* macro.c (enter_macro_context): Only push
	macro_real_token_count (macro) tokens rather than
	macro->count tokens, regardless of
	CPP_OPTION (pfile, track-macro-expansion).

	* c-c++-common/cpp/pr58844-1.c: New test.
	* c-c++-common/cpp/pr58844-2.c: New test.

--- libcpp/macro.c	(revision 207870)
+++ libcpp/macro.c	(revision 207871)
@@ -1115,21 +1115,22 @@ enter_macro_context (cpp_reader *pfile,
 
       if (macro->paramc == 0)
 	{
+	  unsigned tokens_count = macro_real_token_count (macro);
 	  if (CPP_OPTION (pfile, track_macro_expansion))
 	    {
-	      unsigned int i, count = macro->count;
+	      unsigned int i;
 	      const cpp_token *src = macro->exp.tokens;
 	      const struct line_map *map;
 	      source_location *virt_locs = NULL;
-	      _cpp_buff *macro_tokens =
-		tokens_buff_new (pfile, count, &virt_locs);
+	      _cpp_buff *macro_tokens
+		= tokens_buff_new (pfile, tokens_count, &virt_locs);
 
 	      /* Create a macro map to record the locations of the
 		 tokens that are involved in the expansion. LOCATION
 		 is the location of the macro expansion point.  */
-	      map  = linemap_enter_macro (pfile->line_table,
-					  node, location, count);
-	      for (i = 0; i < count; ++i)
+	      map = linemap_enter_macro (pfile->line_table,
+					 node, location, tokens_count);
+	      for (i = 0; i < tokens_count; ++i)
 		{
 		  tokens_buff_add_token (macro_tokens, virt_locs,
 					 src, src->src_loc,
@@ -1141,16 +1142,12 @@ enter_macro_context (cpp_reader *pfile,
 					    virt_locs,
 					    (const cpp_token **)
 					    macro_tokens->base,
-					    count);
-	      num_macro_tokens_counter += count;
+					    tokens_count);
 	    }
 	  else
-	    {
-	      unsigned tokens_count = macro_real_token_count (macro);
-	      _cpp_push_token_context (pfile, node, macro->exp.tokens,
-				       tokens_count);
-	      num_macro_tokens_counter += tokens_count;
-	    }
+	    _cpp_push_token_context (pfile, node, macro->exp.tokens,
+				     tokens_count);
+	  num_macro_tokens_counter += tokens_count;
 	}
 
       if (pragma_buff)
--- gcc/testsuite/c-c++-common/cpp/pr58844-1.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr58844-1.c	(revision 207871)
@@ -0,0 +1,8 @@
+/* PR preprocessor/58844 */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=0" } */
+
+#define A x######x
+int A = 1;
+#define A x######x	/* { dg-message "previous definition" } */
+#define A x##x		/* { dg-warning "redefined" } */
--- gcc/testsuite/c-c++-common/cpp/pr58844-2.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr58844-2.c	(revision 207871)
@@ -0,0 +1,8 @@
+/* PR preprocessor/58844 */
+/* { dg-do compile } */
+/* { dg-options "-ftrack-macro-expansion=2" } */
+
+#define A x######x
+int A = 1;
+#define A x######x	/* { dg-message "previous definition" } */
+#define A x##x		/* { dg-warning "redefined" } */
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-19  Jakub Jelinek  <jakub@redhat.com>

	PR c/37743
	* c-common.c (c_common_nodes_and_builtins): When initializing
	c_uint{16,32,64}_type_node, also set corresponding
	uint{16,32,64}_type_node to the same value.

	* g++.dg/ext/builtin-bswap1.C: New test.
	* c-c++-common/pr37743.c: New test.

--- gcc/c-family/c-common.c	(revision 207923)
+++ gcc/c-family/c-common.c	(revision 207924)
@@ -5610,13 +5610,13 @@ c_common_nodes_and_builtins (void)
     uint8_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT8_TYPE)));
   if (UINT16_TYPE)
-    c_uint16_type_node =
+    c_uint16_type_node = uint16_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT16_TYPE)));
   if (UINT32_TYPE)
-    c_uint32_type_node =
+    c_uint32_type_node = uint32_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT32_TYPE)));
   if (UINT64_TYPE)
-    c_uint64_type_node =
+    c_uint64_type_node = uint64_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT64_TYPE)));
   if (INT_LEAST8_TYPE)
     int_least8_type_node =
--- gcc/testsuite/g++.dg/ext/builtin-bswap1.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/builtin-bswap1.C	(revision 207924)
@@ -0,0 +1,22 @@
+// PR c/37743
+// { dg-do compile }
+
+#if defined(__UINT32_TYPE__) && defined(__INT32_TYPE__)
+
+void foo (__UINT32_TYPE__);
+void foo (__INT32_TYPE__);
+
+void
+bar (__UINT32_TYPE__ x)
+{
+  foo (__builtin_bswap32 (x));
+}
+
+#else
+
+void
+bar ()
+{
+}
+
+#endif
--- gcc/testsuite/c-c++-common/pr37743.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr37743.c	(revision 207924)
@@ -0,0 +1,13 @@
+/* PR c/37743 */
+/* This needs to be run only on targets where __UINT32_TYPE__ is defined
+   to unsigned int.  */
+/* { dg-do compile { target *-*-linux-gnu* } } */
+/* { dg-options "-Wformat" } */
+
+int foo (const char *, ...) __attribute__ ((format (printf, 1, 2)));
+
+void
+bar (unsigned int x)
+{
+  foo ("%x", __builtin_bswap32 (x));
+}
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	* Makefile.in (tree-ssa-uninit.o): Depend on $(PARAMS_H).

	Backport from mainline
	2014-02-21  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/56490
	* params.def (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS): New param.
	* tree-ssa-uninit.c: Include params.h.
	(compute_control_dep_chain): Add num_calls argument, return false
	if it exceed PARAM_UNINIT_CONTROL_DEP_ATTEMPTS param, pass
	num_calls to recursive call.
	(find_predicates): Change dep_chain into normal array, add num_calls
	variable and adjust compute_control_dep_chain caller.
	(find_def_preds): Likewise.

--- gcc/params.def	(revision 207987)
+++ gcc/params.def	(revision 207988)
@@ -1014,6 +1014,12 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,
 	  "strength reduction",
 	  50, 1, 999999)
 
+DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
+	  "uninit-control-dep-attempts",
+	  "Maximum number of nested calls to search for control dependencies "
+	  "during uninitialized variable analysis",
+	  1000, 1, 0)
+
 /*
 Local variables:
 mode:c
--- gcc/tree-ssa-uninit.c	(revision 207987)
+++ gcc/tree-ssa-uninit.c	(revision 207988)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.
 #include "hashtab.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
+#include "params.h"
 
 /* This implements the pass that does predicate aware warning on uses of
    possibly uninitialized variables. The pass first collects the set of
@@ -246,8 +247,8 @@ find_control_equiv_block (basic_block bb
 
 /* Computes the control dependence chains (paths of edges)
    for DEP_BB up to the dominating basic block BB (the head node of a
-   chain should be dominated by it).  CD_CHAINS is pointer to a
-   dynamic array holding the result chains. CUR_CD_CHAIN is the current
+   chain should be dominated by it).  CD_CHAINS is pointer to an
+   array holding the result chains.  CUR_CD_CHAIN is the current
    chain being computed.  *NUM_CHAINS is total number of chains.  The
    function returns true if the information is successfully computed,
    return false if there is no control dependence or not computed.  */
@@ -256,7 +257,8 @@ static bool
 compute_control_dep_chain (basic_block bb, basic_block dep_bb,
                            vec<edge> *cd_chains,
                            size_t *num_chains,
-                           vec<edge> *cur_cd_chain)
+			   vec<edge> *cur_cd_chain,
+			   int *num_calls)
 {
   edge_iterator ei;
   edge e;
@@ -267,6 +269,10 @@ compute_control_dep_chain (basic_block b
   if (EDGE_COUNT (bb->succs) < 2)
     return false;
 
+  if (*num_calls > PARAM_VALUE (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS))
+    return false;
+  ++*num_calls;
+
   /* Could  use a set instead.  */
   cur_chain_len = cur_cd_chain->length ();
   if (cur_chain_len > MAX_CHAIN_LEN)
@@ -306,7 +312,7 @@ compute_control_dep_chain (basic_block b
 
           /* Now check if DEP_BB is indirectly control dependent on BB.  */
           if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
-                                         num_chains, cur_cd_chain))
+					 num_chains, cur_cd_chain, num_calls))
             {
               found_cd_chain = true;
               break;
@@ -438,14 +444,12 @@ find_predicates (vec<use_pred_info_t> **
                  basic_block use_bb)
 {
   size_t num_chains = 0, i;
-  vec<edge> *dep_chains = 0;
+  int num_calls = 0;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
   vec<edge> cur_chain = vNULL;
   bool has_valid_pred = false;
   basic_block cd_root = 0;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   /* First find the closest bb that is control equivalent to PHI_BB
      that also dominates USE_BB.  */
   cd_root = phi_bb;
@@ -458,20 +462,16 @@ find_predicates (vec<use_pred_info_t> **
         break;
     }
 
-  compute_control_dep_chain (cd_root, use_bb,
-                             dep_chains, &num_chains,
-                             &cur_chain);
+  compute_control_dep_chain (cd_root, use_bb, dep_chains, &num_chains,
+			     &cur_chain, &num_calls);
 
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds,
-                                              num_preds);
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds,
+					    num_preds);
   /* Free individual chain  */
   cur_chain.release ();
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }
 
@@ -539,16 +539,13 @@ find_def_preds (vec<use_pred_info_t> **p
                 size_t *num_preds, gimple phi)
 {
   size_t num_chains = 0, i, n;
-  vec<edge> *dep_chains = 0;
+  vec<edge> dep_chains[MAX_NUM_CHAINS];
   vec<edge> cur_chain = vNULL;
   vec<edge> def_edges = vNULL;
   bool has_valid_pred = false;
   basic_block phi_bb, cd_root = 0;
   struct pointer_set_t *visited_phis;
 
-  typedef vec<edge> vec_edge_heap;
-  dep_chains = XCNEWVEC (vec_edge_heap, MAX_NUM_CHAINS);
-
   phi_bb = gimple_bb (phi);
   /* First find the closest dominating bb to be
      the control dependence root  */
@@ -567,38 +564,33 @@ find_def_preds (vec<use_pred_info_t> **p
   for (i = 0; i < n; i++)
     {
       size_t prev_nc, j;
+      int num_calls = 0;
       edge opnd_edge;
 
       opnd_edge = def_edges[i];
       prev_nc = num_chains;
-      compute_control_dep_chain (cd_root, opnd_edge->src,
-                                 dep_chains, &num_chains,
-                                 &cur_chain);
-      /* Free individual chain  */
-      cur_chain.release ();
+      compute_control_dep_chain (cd_root, opnd_edge->src, dep_chains,
+				 &num_chains, &cur_chain, &num_calls);
 
       /* Now update the newly added chains with
          the phi operand edge:  */
       if (EDGE_COUNT (opnd_edge->src->succs) > 1)
         {
-          if (prev_nc == num_chains
-              && num_chains < MAX_NUM_CHAINS)
-            num_chains++;
+	  if (prev_nc == num_chains && num_chains < MAX_NUM_CHAINS)
+	    dep_chains[num_chains++] = vNULL;
           for (j = prev_nc; j < num_chains; j++)
-            {
-              dep_chains[j].safe_push (opnd_edge);
-            }
+	    dep_chains[j].safe_push (opnd_edge);
         }
     }
 
+  /* Free individual chain  */
+  cur_chain.release ();
+
   has_valid_pred
-      = convert_control_dep_chain_into_preds (dep_chains,
-                                              num_chains,
-                                              preds,
-                                              num_preds);
+    = convert_control_dep_chain_into_preds (dep_chains, num_chains, preds,
+					    num_preds);
   for (i = 0; i < num_chains; i++)
     dep_chains[i].release ();
-  free (dep_chains);
   return has_valid_pred;
 }
 
--- gcc/Makefile.in	2013-12-11 14:43:58.000000000 +0100
+++ gcc/Makefile.in	2014-03-05 21:30:28.839269860 +0100
@@ -2256,7 +2256,7 @@ tree-ssa-uninit.o : tree-ssa-uninit.c $(
    $(FUNCTION_H) $(TM_H) coretypes.h \
    $(TREE_PASS_H) $(BASIC_BLOCK_H) $(BITMAP_H) \
    $(FLAGS_H) $(HASHTAB_H) pointer-set.h \
-   $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
+   $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) $(PARAMS_H)
 tree-ssa.o : tree-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(TM_P_H) $(EXPR_H) $(DIAGNOSTIC_H) \
    toplev.h $(FUNCTION_H) $(TM_H) coretypes.h \
2014-03-06  Jakub Jelinek  <jakub@redhat.com>

	Backport from mainline
	2014-02-08  Jakub Jelinek  <jakub@redhat.com>

	PR ipa/60026
	* ipa-cp.c (determine_versionability): Fail at -O0
	or __attribute__((optimize (0))) or -fno-ipa-cp functions.
	* tree-sra.c (ipa_sra_preliminary_function_checks): Similarly.

	2014-02-06  Jakub Jelinek  <jakub@redhat.com>

	PR target/60062
	* tree.h (opts_for_fn): New inline function.
	(opt_for_fn): Define.
	* config/i386/i386.c (ix86_function_regparm): Use
	opt_for_fn (decl, optimize) instead of optimize.

	* gcc.c-torture/execute/pr60062.c: New test.
	* gcc.c-torture/execute/pr60072.c: New test.

	2014-02-04  Jakub Jelinek  <jakub@redhat.com>

	PR ipa/60026
	* c-c++-common/torture/pr60026.c: New test.

--- gcc/tree.h	(revision 207548)
+++ gcc/tree.h	(revision 207549)
@@ -6546,4 +6546,18 @@ builtin_decl_implicit_p (enum built_in_f
 	  && builtin_info.implicit_p[uns_fncode]);
 }
 
+/* Return pointer to optimization flags of FNDECL.  */
+static inline struct cl_optimization *
+opts_for_fn (const_tree fndecl)
+{
+  tree fn_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+  if (fn_opts == NULL_TREE)
+    fn_opts = optimization_default_node;
+  return TREE_OPTIMIZATION (fn_opts);
+}
+
+/* opt flag for function FNDECL, e.g. opts_for_fn (fndecl, optimize) is
+   the optimization level of function fndecl.  */
+#define opt_for_fn(fndecl, opt) (opts_for_fn (fndecl)->x_##opt)
+
 #endif  /* GCC_TREE_H  */
--- gcc/ipa-cp.c	(revision 207620)
+++ gcc/ipa-cp.c	(revision 207621)
@@ -444,6 +444,9 @@ determine_versionability (struct cgraph_
     reason = "not a tree_versionable_function";
   else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
     reason = "insufficient body availability";
+  else if (!opt_for_fn (node->symbol.decl, optimize)
+	   || !opt_for_fn (node->symbol.decl, flag_ipa_cp))
+    reason = "non-optimized function";
 
   if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
     fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
--- gcc/tree-sra.c	(revision 207620)
+++ gcc/tree-sra.c	(revision 207621)
@@ -4900,6 +4900,14 @@ ipa_sra_preliminary_function_checks (str
       return false;
     }
 
+  if (!opt_for_fn (node->symbol.decl, optimize)
+      || !opt_for_fn (node->symbol.decl, flag_ipa_sra))
+    {
+      if (dump_file)
+	fprintf (dump_file, "Function not optimized.\n");
+      return false;
+    }
+
   if (DECL_VIRTUAL_P (current_function_decl))
     {
       if (dump_file)
--- gcc/config/i386/i386.c	(revision 207548)
+++ gcc/config/i386/i386.c	(revision 207549)
@@ -5608,7 +5608,12 @@ ix86_function_regparm (const_tree type,
   /* Use register calling convention for local functions when possible.  */
   if (decl
       && TREE_CODE (decl) == FUNCTION_DECL
-      && optimize
+      /* Caller and callee must agree on the calling convention, so
+	 checking here just optimize means that with
+	 __attribute__((optimize (...))) caller could use regparm convention
+	 and callee not, or vice versa.  Instead look at whether the callee
+	 is optimized or not.  */
+      && opt_for_fn (decl, optimize)
       && !(profile_flag && !flag_fentry))
     {
       /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified.  */
--- gcc/testsuite/gcc.c-torture/execute/pr60062.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr60062.c	(revision 207549)
@@ -0,0 +1,25 @@
+/* PR target/60062 */
+
+int a;
+
+static void
+foo (const char *p1, int p2)
+{
+  if (__builtin_strcmp (p1, "hello") != 0)
+    __builtin_abort ();
+}
+
+static void
+bar (const char *p1)
+{
+  if (__builtin_strcmp (p1, "hello") != 0)
+    __builtin_abort ();
+}
+
+__attribute__((optimize (0))) int
+main ()
+{
+  foo ("hello", a);
+  bar ("hello");
+  return 0;
+}
--- gcc/testsuite/gcc.c-torture/execute/pr60072.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr60072.c	(revision 207549)
@@ -0,0 +1,16 @@
+/* PR target/60072 */
+
+int c = 1;
+
+__attribute__ ((optimize (1)))
+static int *foo (int *p)
+{
+  return p;
+}
+
+int
+main ()
+{
+  *foo (&c) = 2;
+  return c - 2;
+}
--- gcc/testsuite/c-c++-common/torture/pr60026.c	(revision 0)
+++ gcc/testsuite/c-c++-common/torture/pr60026.c	(revision 207463)
@@ -0,0 +1,28 @@
+/* PR ipa/60026 */
+/* { dg-do compile } */
+
+struct S { int f; } a;
+
+__attribute__((optimize (0)))
+struct S foo (int x, struct S y)
+{
+  int b = y.f;
+  return a; 
+}
+
+void
+bar ()
+{
+  while (a.f)
+    {
+      struct S c = {0};
+      foo (0, c);
+    }
+}
+
+int
+main ()
+{
+  bar (); 
+  return 0;
+}

Comments

Gerald Pfeifer March 8, 2014, 10:08 p.m. UTC | #1
On Thu, 6 Mar 2014, Jakub Jelinek wrote:
> I've backported a few bugfixes to 4.8 branch, bootstrapped/regtested 
> on x86_64-linux and i686-linux, committed to branch.

This reminds my:  what are your plans doing new release off that 
branch?  The last one has been five months ago.  What is the rough
interval between releases you have in mind?

And how about GCC 4.7.4?  Any plans for that and closing the branch
afterwards?  Or do you plan to keep 4.7 alive for longer?

Gerald
Jakub Jelinek March 9, 2014, 4:26 p.m. UTC | #2
On Sat, Mar 08, 2014 at 11:08:14PM +0100, Gerald Pfeifer wrote:
> On Thu, 6 Mar 2014, Jakub Jelinek wrote:
> > I've backported a few bugfixes to 4.8 branch, bootstrapped/regtested 
> > on x86_64-linux and i686-linux, committed to branch.
> 
> This reminds my:  what are your plans doing new release off that 
> branch?  The last one has been five months ago.  What is the rough
> interval between releases you have in mind?

Last year we did 4.n-1 and 4.n-2 releases a short time after the 4.n
release, given the focus on making 4.9 stable now I'd say we should do the
same thing this year as well.

> And how about GCC 4.7.4?  Any plans for that and closing the branch
> afterwards?  Or do you plan to keep 4.7 alive for longer?

	Jakub
diff mbox

Patch

--- libcpp/files.c	(revision 200375)
+++ libcpp/files.c	(revision 200376)
@@ -983,6 +983,7 @@  _cpp_stack_include (cpp_reader *pfile, c
 {
   struct cpp_dir *dir;
   _cpp_file *file;
+  bool stacked;
 
   dir = search_path_head (pfile, fname, angle_brackets, type);
   if (!dir)
@@ -993,19 +994,26 @@  _cpp_stack_include (cpp_reader *pfile, c
   if (type == IT_DEFAULT && file == NULL)
     return false;
 
-  /* Compensate for the increment in linemap_add that occurs in
-     _cpp_stack_file.  In the case of a normal #include, we're
-     currently at the start of the line *following* the #include.  A
-     separate source_location for this location makes no sense (until
-     we do the LC_LEAVE), and complicates LAST_SOURCE_LINE_LOCATION.
-     This does not apply if we found a PCH file (in which case
-     linemap_add is not called) or we were included from the
-     command-line.  */
+  /* Compensate for the increment in linemap_add that occurs if
+      _cpp_stack_file actually stacks the file.  In the case of a
+     normal #include, we're currently at the start of the line
+     *following* the #include.  A separate source_location for this
+     location makes no sense (until we do the LC_LEAVE), and
+     complicates LAST_SOURCE_LINE_LOCATION.  This does not apply if we
+     found a PCH file (in which case linemap_add is not called) or we
+     were included from the command-line.  */
   if (file->pchname == NULL && file->err_no == 0
       && type != IT_CMDLINE && type != IT_DEFAULT)
     pfile->line_table->highest_location--;
 
-  return _cpp_stack_file (pfile, file, type == IT_IMPORT);
+  stacked = _cpp_stack_file (pfile, file, type == IT_IMPORT);
+
+  if (!stacked)
+    /* _cpp_stack_file didn't stack the file, so let's rollback the
+       compensation dance we performed above.  */
+    pfile->line_table->highest_location++;
+
+  return stacked;
 }
 
 /* Could not open FILE.  The complication is dependency output.  */
--- gcc/testsuite/c-c++-common/cpp/pr60400.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400.c	(revision 208272)
@@ -0,0 +1,13 @@ 
+/* PR preprocessor/60400 */
+/* { dg-do compile } */
+/* { dg-options "-trigraphs -Wtrigraphs" } */
+
+??=include "pr60400-1.h"
+??=include "pr60400-2.h"
+
+/* { dg-warning "trigraph" "" { target *-*-* } 1 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 2 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 3 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 4 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 5 } */
+/* { dg-warning "trigraph" "" { target *-*-* } 6 } */
--- gcc/testsuite/c-c++-common/cpp/pr60400-1.h	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400-1.h	(revision 208272)
@@ -0,0 +1,3 @@ 
+??=ifndef PR60400_1_H
+??=define PR60400_1_H
+??=endif
--- gcc/testsuite/c-c++-common/cpp/pr60400-2.h	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr60400-2.h	(revision 208272)
@@ -0,0 +1,4 @@ 
+??=ifndef PR60400_2_H
+??=define PR60400_2_H
+??=include "pr60400-1.h"
+??=endif