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]

Re: [PATCH][LTO] Fix PR46606


On Tue, 23 Nov 2010, Richard Guenther wrote:

> 
> 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.

Bootstrapped and tested on x86_64-unknown-linux-gnu, SPEC 2k6 built
with -flto -fwhole-program with no problems.
 
> 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;
>   		}
>   
> 
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex


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