out of bounds access in insn-automata.c
Aldy Hernandez
aldyh@redhat.com
Thu Mar 24 10:17:00 GMT 2016
On 03/23/2016 10:25 AM, Bernd Schmidt wrote:
> On 03/23/2016 07:32 AM, Aldy Hernandez wrote:
>>
>> int
>> maximal_insn_latency (rtx insn)
>> {
>> int insn_code;
>>
>> if (insn == 0)
>> insn_code = DFA__ADVANCE_CYCLE;
>>
>>
>> else
>> {
>> insn_code = dfa_insn_code (as_a <rtx_insn *> (insn));
>> if (insn_code > DFA__ADVANCE_CYCLE)
>> return 0;
>> }
>> return internal_maximal_insn_latency (insn_code, insn);
>> }
>>
>> In the case where insn==0, insn_code is set to the size of
>> default_latencies[] which will get accessed in the return.
>>
>> Does insn==0 never happen?
>
> I suspect it never happens in this function. I'd add a gcc_assert to
> that effect and try a bootstrap/test. Hmm, it seems to be a sel-sched
> only thing so a normal bootstrap would be meaningless, but from the
> context it looks fairly clearly like insn is always nonnull.
Vlad. Bernd. Thanks for your input.
I've added the assert on the caller (maximal_insn_latency), because as
you mentioned, the helper function is used for other things in which
insn==0 can happen.
Now we generate:
int
maximal_insn_latency (rtx insn)
{
int insn_code;
gcc_assert (insn != 0); // <<<<--- Added code.
if (insn == 0)
insn_code = DFA__ADVANCE_CYCLE;
else
{
insn_code = dfa_insn_code (as_a <rtx_insn *> (insn));
if (insn_code > DFA__ADVANCE_CYCLE)
return 0;
}
return internal_maximal_insn_latency (insn_code, insn);
}
>
> It looks like this block of code is written by a helper function that is
> really intended for other purposes than for maximal_insn_latency. Might
> be worth changing to
> int insn_code = dfa_insn_code (as_a <rtx_insn *> (insn));
> gcc_assert (insn_code <= DFA__ADVANCE_CYCLE);
dfa_insn_code_* and friends can return > DFA__ADVANCE_CYCLE so I can't
put that assert on the helper function.
While I was at it, I changed the helper function comment to reflect what
it has been generating. It was wrong.
First round of tests was ok, but test machine died. OK pending tests?
Aldy
-------------- next part --------------
+
+ * genautomata.c (output_maximal_insn_latency_func): Assert that
+ insn is non-null.
+ (output_internal_insn_code_evaluation): Fix comment to match
+ generated code.
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index e3a6c59..91abd2e 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -8113,14 +8113,14 @@ output_internal_trans_func (void)
/* Output code
- if (insn != 0)
+ if (insn == 0)
+ insn_code = DFA__ADVANCE_CYCLE;
+ else
{
insn_code = dfa_insn_code (insn);
if (insn_code > DFA__ADVANCE_CYCLE)
return code;
}
- else
- insn_code = DFA__ADVANCE_CYCLE;
where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
code denotes CODE. */
@@ -8527,6 +8527,7 @@ output_maximal_insn_latency_func (void)
"maximal_insn_latency", INSN_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n",
INTERNAL_INSN_CODE_NAME);
+ fprintf (output_file, " gcc_assert (%s != 0);\n", INSN_PARAMETER_NAME);
output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
INTERNAL_INSN_CODE_NAME, 0);
fprintf (output_file, " return %s (%s, %s);\n}\n\n",
More information about the Gcc
mailing list