[PATCH] Fix PR45874

Martin Jambor mjambor@suse.cz
Wed Oct 13 12:48:00 GMT 2010


On Wed, Oct 13, 2010 at 12:04:48PM +0200, Richard Guenther wrote:
> 
> This fixes PR45874 - we need to fixup the CFG when gsi_replace
> fixes up EH.  This does it the proper way manually.
> 
> Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
> 
> Richard.
> 
> 2010-10-13  Richard Guenther  <rguenther@suse.de>
> 
> 	PR middle-end/45874
> 	* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee):
> 	Fixup the CFG when EH was fixed up.
> 

Isn't it necessary to return TODO_cleanup_cfg from the pass that does
this?  If so, we either need to communicate that we have changed the
statement to inline_transform or return TODO_cleanup_cfg from there
unconditionally (which I think would be acceptable in this particular
function).  Or is it somehow not necessary?

Thanks,

Martin


> 	* g++.dg/torture/pr45874.C: New testcase.
> 
> Index: gcc/cgraphunit.c
> ===================================================================
> *** gcc/cgraphunit.c	(revision 165412)
> --- gcc/cgraphunit.c	(working copy)
> *************** cgraph_redirect_edge_call_stmt_to_callee
> *** 2167,2179 ****
>   	SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
>   
>         gsi = gsi_for_stmt (e->call_stmt);
> !       gsi_replace (&gsi, new_stmt, true);
>       }
>     else
>       {
>         new_stmt = e->call_stmt;
>         gimple_call_set_fndecl (new_stmt, e->callee->decl);
>         update_stmt (new_stmt);
>       }
>   
>     cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
> --- 2167,2183 ----
>   	SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
>   
>         gsi = gsi_for_stmt (e->call_stmt);
> !       gsi_replace (&gsi, new_stmt, false);
> !       if (maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt))
> ! 	gimple_purge_dead_eh_edges (gimple_bb (new_stmt));
>       }
>     else
>       {
>         new_stmt = e->call_stmt;
>         gimple_call_set_fndecl (new_stmt, e->callee->decl);
>         update_stmt (new_stmt);
> +       if (maybe_clean_eh_stmt (new_stmt))
> + 	gimple_purge_dead_eh_edges (gimple_bb (new_stmt));
>       }
>   
>     cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
> Index: gcc/testsuite/g++.dg/torture/pr45874.C
> ===================================================================
> *** gcc/testsuite/g++.dg/torture/pr45874.C	(revision 0)
> --- gcc/testsuite/g++.dg/torture/pr45874.C	(revision 0)
> ***************
> *** 0 ****
> --- 1,58 ----
> + // { dg-do compile }
> + 
> + typedef struct {
> + } IppLibraryVersion;
> + typedef unsigned char Ipp8u;
> + typedef unsigned int Ipp32u;
> + typedef signed int Ipp32s;
> + typedef enum e_vm_Status {
> +     VM_OK = 0,     VM_OPERATION_FAILED =-999,     VM_NOT_INITIALIZED =-998,     VM_TIMEOUT =-987,     VM_NOT_ENOUGH_DATA =-996,      VM_NULL_PTR =-995,     VM_SO_CANT_LOAD =-994,     VM_SO_INVALID_HANDLE =-993,     VM_SO_CANT_GET_ADDR =-992 }
> +     vm_status;
> +     typedef Ipp32s Status;
> +     class MediaReceiver {
> +     };
> + class MediaBuffer : public MediaReceiver {
> + };
> + struct TrackInfo {
> + };
> + struct Mpeg2TrackInfo : public TrackInfo     {
> + };
> + class BitstreamReader     {
> + public:          BitstreamReader(void);
> + 		 virtual ~BitstreamReader(void) {
> + 		 }
> + 		 Ipp32u GetBits(Ipp32s iNum);
> + 		 void SkipBits(Ipp32s iNum);
> + protected:          virtual void Refresh(void);
> + 		    Ipp32s m_iReadyBits;
> + };
> + class FrameConstructor : public MediaBuffer     {
> + };
> + class VideoFrameConstructor : public FrameConstructor     {
> + };
> + class Mpeg2FrameConstructor : public VideoFrameConstructor     {
> +     static Status ParsePictureHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo);
> + };
> + Status Mpeg2FrameConstructor::ParsePictureHeader(Ipp8u *buf, Ipp32s iLen, Mpeg2TrackInfo *pInfo) {
> +     BitstreamReader bs;
> +     bs.SkipBits(32 + 4 + 4 + 4 + 4 + 4 + 2);
> +     bs.SkipBits(1 + 1 + 1 + 1 + 1 + 1 + 1);
> +     bs.SkipBits(5);
> +     bs.SkipBits(3);
> +     Ipp8u source_format;
> +     bs.SkipBits(22);
> +     bs.SkipBits(8);
> +     if (7 == source_format)     {
> + 	Ipp8u ufep = (Ipp8u)bs.GetBits(3);
> + 	if (0x01 == ufep)         {
> + 	    bs.SkipBits(10);
> + 	}
> +     }
> + }
> + void BitstreamReader::SkipBits(Ipp32s iNum) {
> +     if (iNum <= m_iReadyBits)     {
> + 	m_iReadyBits -= iNum;
> + 	Refresh();
> +     }
> + }
> + void BitstreamReader::Refresh(void) { }



More information about the Gcc-patches mailing list