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]

fix middle-end/11767


Compare and branch in different basic blocks is dangerous, because
it's highly likely that the flags register will get clobbered in
between.  Fortunately, that can easily be avoided.


r~


        * coverage.c (coverage_counter_ref): Set MEM_NOTRAP_P.
        * optabs.c (prepare_cmp_insn): Force trapping memories to registers
        before the compare, if flag_non_call_exceptions.
	* g++.dg/other/profile1.C: New.

Index: coverage.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.27.4.1
diff -c -p -d -r1.27.4.1 coverage.c
*** coverage.c	18 Jan 2004 17:42:32 -0000	1.27.4.1
--- coverage.c	3 Mar 2004 00:38:04 -0000
*************** coverage_counter_ref (unsigned counter, 
*** 397,402 ****
--- 397,403 ----
    ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
    ref = gen_rtx_MEM (mode, ref);
    set_mem_alias_set (ref, new_alias_set ());
+   MEM_NOTRAP_P (ref) = 1;
  
    return ref;
  }
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.204.4.1
diff -c -p -d -r1.204.4.1 optabs.c
*** optabs.c	23 Jan 2004 23:36:01 -0000	1.204.4.1
--- optabs.c	3 Mar 2004 00:38:04 -0000
*************** prepare_cmp_insn (rtx *px, rtx *py, enum
*** 3651,3656 ****
--- 3651,3666 ----
        return;
      }
  
+   /* Don't allow operands to the compare to trap, as that can put the
+      compare and branch in different basic blocks.  */
+   if (flag_non_call_exceptions)
+     {
+       if (may_trap_p (x))
+ 	x = force_reg (mode, x);
+       if (may_trap_p (y))
+ 	y = force_reg (mode, y);
+     }
+ 
    *px = x;
    *py = y;
    if (can_compare_p (*pcomparison, mode, purpose))
Index: testsuite/g++.dg/other/profile1.C
===================================================================
RCS file: testsuite/g++.dg/other/profile1.C
diff -N testsuite/g++.dg/other/profile1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/other/profile1.C	3 Mar 2004 00:38:09 -0000
***************
*** 0 ****
--- 1,51 ----
+ // PR 11767
+ // { dg-do run }
+ // { dg-options "-fnon-call-exceptions -fprofile-arcs" }
+ 
+ #include <string>
+ 
+ typedef unsigned long ACE_UINT32;
+ extern "C" void abort();
+ 
+ static ACE_UINT32 const msc_maxCurrencyID = 9999;
+ 
+ class ResourceBalanceType2
+ {
+   public:
+    explicit ResourceBalanceType2(
+       ACE_UINT32 resourceBalanceTypeID,
+       ACE_UINT32 isoValue,
+       const std::string& rc_shortName,
+       const std::string& rc_symbol
+     );
+   public:
+     const ACE_UINT32 mc_resBalTypeID;
+     const ACE_UINT32 mc_isoValue;
+     const std::string mc_shortName;
+     const std::string mc_symbol;
+ };
+ 
+ void f(){}
+ 
+ ResourceBalanceType2::ResourceBalanceType2(
+     ACE_UINT32 resourceBalanceTypeID,
+     ACE_UINT32 isoValue,
+     const std::string& rc_shortName,
+     const std::string& rc_symbol)
+   : mc_resBalTypeID(resourceBalanceTypeID),
+     mc_isoValue(isoValue),
+     mc_shortName(rc_shortName),
+     mc_symbol(rc_symbol)
+ {
+   bool isGreater = (mc_isoValue > msc_maxCurrencyID);
+   f();
+   bool temp = mc_isoValue > msc_maxCurrencyID;
+   if (!isGreater) abort();
+   if (!temp) abort();
+ }
+ 
+ int main (int argc, char * argv[])
+ {
+   ACE_UINT32 const mc_isoValue = 10000;
+   ResourceBalanceType2 rbResourceBalanceType2(3, mc_isoValue, "ATM", "M");
+ }


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