This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix middle-end/11767
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 2 Mar 2004 16:52:28 -0800
- Subject: 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");
+ }