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][LTO] Fix PR46606


For TUs with type ODR violations we can end up ICEing during statement
input.  The following old patch of mine makes us emit a (hopefully)
helpful warning instead and tries to recover by papering over with
VIEW_CONVERT exprs.  For the testcase in the PR we emit

> ./xgcc -B. -o t -flto 1.c 2.c
In function 'g':
2.c:16:6: warning: Use of type 'struct list_node' with two mismatching 
declarations at field '<anonymous>' [enabled by default]
1.c:11:3: note: original type declared here
2.c:11:3: note: field in mismatching type declared here

instead of ICEing on the present assert.  Note that outputting reasonable
locations for the notes isn't easy, but the above might be as good
as we can get.

I'll give this (and the other patch) a round of SPEC compile as well.

Ok for trunk?

Thanks,
Richard.

2010-11-23  Richard Guenther  <rguenther@suse.de>

	PR lto/46606
	* lto-streamer-in.c (input_gimple_stmt): When we cannot find
	a FIELD_DECL that is type correct issue a warning and fixup
	with a VIEW_CONVERT_EXPR.

Index: gcc/lto-streamer-in.c
===================================================================
*** gcc/lto-streamer-in.c	(revision 167073)
--- gcc/lto-streamer-in.c	(working copy)
*************** input_gimple_stmt (struct lto_input_bloc
*** 956,980 ****
  	      if (TREE_CODE (op) == COMPONENT_REF)
  		{
  		  tree field, type, tem;
  		  field = TREE_OPERAND (op, 1);
  		  type = DECL_CONTEXT (field);
  		  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
  		    {
! 		      if (tem == field
! 			  || (gimple_types_compatible_p (TREE_TYPE (tem),
! 							 TREE_TYPE (field),
! 							 GTC_DIAG)
! 			      && DECL_NONADDRESSABLE_P (tem)
! 				 == DECL_NONADDRESSABLE_P (field)
! 			      && gimple_compare_field_offset (tem, field)))
  			break;
  		    }
  		  /* In case of type mismatches across units we can fail
  		     to unify some types and thus not find a proper
! 		     field-decl here.  So only assert here if checking
! 		     is enabled.  */
! 		  gcc_checking_assert (tem != NULL_TREE);
! 		  if (tem != NULL_TREE)
  		    TREE_OPERAND (op, 1) = tem;
  		}
  
--- 956,1016 ----
  	      if (TREE_CODE (op) == COMPONENT_REF)
  		{
  		  tree field, type, tem;
+ 		  tree closest_match = NULL_TREE;
  		  field = TREE_OPERAND (op, 1);
  		  type = DECL_CONTEXT (field);
  		  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
  		    {
! 		      if (tem == field)
  			break;
+ 		      if (DECL_NONADDRESSABLE_P (tem)
+ 			  == DECL_NONADDRESSABLE_P (field)
+ 			  && gimple_compare_field_offset (tem, field))
+ 			{
+ 			  if (gimple_types_compatible_p (TREE_TYPE (tem),
+ 							 TREE_TYPE (field),
+ 							 GTC_DIAG))
+ 			    break;
+ 			  else
+ 			    closest_match = tem;
+ 			}
  		    }
  		  /* In case of type mismatches across units we can fail
  		     to unify some types and thus not find a proper
! 		     field-decl here.  */
! 		  if (tem == NULL_TREE)
! 		    {
! 		      /* Thus, emit a ODR violation warning.  */
! 		      if (warning_at (gimple_location (stmt), 0,
! 				      "Use of type %<%E%> with two mismatching "
! 				      "declarations at field %<%E%>",
! 				      type, TREE_OPERAND (op, 1)))
! 			{
! 			  if (TYPE_FIELDS (type))
! 			    inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
! 				    "original type declared here");
! 			  inform (DECL_SOURCE_LOCATION (TREE_OPERAND (op, 1)),
! 				  "field in mismatching type declared here");
! 			  if (TYPE_NAME (TREE_TYPE (field))
! 			      && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
! 				  == TYPE_DECL))
! 			    inform (DECL_SOURCE_LOCATION
! 				      (TYPE_NAME (TREE_TYPE (field))),
! 				    "type of field declared here");
! 			  if (closest_match
! 			      && TYPE_NAME (TREE_TYPE (closest_match))
! 			      && (TREE_CODE (TYPE_NAME
! 				   (TREE_TYPE (closest_match))) == TYPE_DECL))
! 			    inform (DECL_SOURCE_LOCATION
! 				      (TYPE_NAME (TREE_TYPE (closest_match))),
! 				    "type of mismatching field declared here");
! 			}
! 		      /* And finally fixup the types.  */
! 		      TREE_OPERAND (op, 0)
! 			= build1 (VIEW_CONVERT_EXPR, type,
! 				  TREE_OPERAND (op, 0));
! 		    }
! 		  else
  		    TREE_OPERAND (op, 1) = tem;
  		}
  


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