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] fix PR39701 testsuite failures


Interestingly enough, these failures had three different root causes,
and each of them triggered a different observation on something dubious
in GCC.

One was due to a disabled folding due to my patch when
-fno-delete-null-pointer-checks (including -O0 -O1).  I fixed this by
considering &x to be non-zero if x is stack allocated.

  Observation: I think however that it does not make sense to have
  -fdelete-null-pointer-checks only at -O2 or higher -- it it is not
  an optimization option, rather it describes the semantics of the
  target, and it should be enabled uniformly at all optimization levels.
  If there are places that we consider optimizations, they should be
  guarded by "(optimize >= 2 && flag_delete_null_pointer_checks).

One is a Fortran front-end bug due to the same disabled folding.  There
is a mismatch in that "&stat" is compared with a zero constant whose
type is "stat"'s type.

  Observation: This is easily fixed, but can be improved by just
  deleting the conditionals emitted for the Fortran ALLOCATE intrinsics.
  It never happens that those conditionals of the form "pstat == 0"
  enter the "then" block, because pstat is always an ADDR_EXPR of a
  stack-allocated variable.  It may be easier to just pass around the
  DECL of the stat variable itself.  I'll leave this to the Fortran
  maintainers.

The third kind of failure is in the PR36901 testcases, which do

  int sc = (&sc > 0);

to emit a pedwarn, and this now triggers an "initializer is not
constant" error when -fno-delete-null-pointer-checks.  Previously, the
comparison was folded to true.  My first impression is that the warning
*is* correct (you need to wait until linking to know the address of &sc
with -fno-delete-null-pointer-checks).  So I'm changing it to

  int sc = (&sc > 0) ? 1 : 1;

This abuses the COND ? A : A folding to make sure that the initializer
is considered constant.

  Observation: I'm CCing Joseph to understand how and if this is correct
  from a C standard point of view, since this seems to me like a case
  of extra folding performed by GCC on initializers.

I'm posting this early to give maintainers time to comment since the
patch touches many areas; in the meanwhile I bubblestrapped the patch on
i686-pc-linux-gnu, and the affected tests now pass.  A full
bootstrap/regtest is running (this time *with* the patch, unlike
yesterday...).

Paolo
2009-04-10  Paolo Bonzini  <bonzini@gnu.org>

	* fold-const.c (tree_single_nonzero_warnv_p): Pass non-static
	variables as non-NULL even with -fdelete-null-pointer-checks.

fortran:
2009-04-10  Paolo Bonzini  <bonzini@gnu.org>

	* trans.c (gfc_allocate_with_status): Fix type mismatches
	on "pstat == 0".

testsuite:
2009-04-10  Paolo Bonzini  <bonzini@gnu.org>

	* gcc.dg/pr36901.h: Make initializer foldable to constant.

Index: fold-const.c
===================================================================
--- fold-const.c	(revision 145846)
+++ fold-const.c	(working copy)
@@ -15017,8 +15017,12 @@ tree_single_nonzero_warnv_p (tree t, boo
 	if (!base)
 	  return false;
 
-	/* Weak declarations may link to NULL.  */
-	if (DECL_P (base) && flag_delete_null_pointer_checks)
+	/* Weak declarations may link to NULL.  Other things may also be NULL
+	   so protect with -fdelete-null-pointer-checks; but not variables
+	   allocated on the stack.  */
+	if (DECL_P (base)
+	    && (flag_delete_null_pointer_checks
+		|| (TREE_CODE (base) == VAR_DECL && !TREE_STATIC (base))))
 	  return !VAR_OR_FUNCTION_DECL_P (base) || !DECL_WEAK (base);
 
 	/* Constants are never weak.  */
Index: fortran/trans.c
===================================================================
--- fortran/trans.c	(revision 145840)
+++ fortran/trans.c	(working copy)
@@ -605,8 +605,8 @@ gfc_allocate_with_status (stmtblock_t * 
 			 fold_build1 (INDIRECT_REF, status_type, status),
 			 build_int_cst (status_type, 0));
       tmp = fold_build3 (COND_EXPR, void_type_node,
-			 fold_build2 (NE_EXPR, boolean_type_node,
-				      status, build_int_cst (status_type, 0)),
+			 fold_build2 (NE_EXPR, boolean_type_node, status,
+				      build_int_cst (TREE_TYPE (status), 0)),
 			 tmp, build_empty_stmt ());
       gfc_add_expr_to_block (block, tmp);
     }
@@ -630,7 +630,7 @@ gfc_allocate_with_status (stmtblock_t * 
 			   build_int_cst (pvoid_type_node, 0));
 
       tmp = fold_build2 (EQ_EXPR, boolean_type_node, status,
-			 build_int_cst (status_type, 0));
+			 build_int_cst (TREE_TYPE (status), 0));
       error = fold_build3 (COND_EXPR, void_type_node, tmp, error,
 			   gfc_finish_block (&set_status_block));
     }
@@ -653,7 +653,7 @@ gfc_allocate_with_status (stmtblock_t * 
       tree tmp2;
 
       cond = fold_build2 (EQ_EXPR, boolean_type_node, status,
-			  build_int_cst (status_type, 0));
+			  build_int_cst (TREE_TYPE (status), 0));
       tmp2 = fold_build2 (MODIFY_EXPR, status_type,
 			  fold_build1 (INDIRECT_REF, status_type, status),
 			  build_int_cst (status_type, LIBERROR_ALLOCATION));
Index: testsuite/gcc.dg/pr36901.h
===================================================================
--- testsuite/gcc.dg/pr36901.h	(revision 145840)
+++ testsuite/gcc.dg/pr36901.h	(working copy)
@@ -1,2 +1,2 @@
-int sc = (&sc > 0);
+int sc = (&sc > 0) ? 1 : 1;
 

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