This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] PR19917: Calls to weak functions may trap
- From: Graham Stott <graham dot stott at btinternet dot com>
- To: Roger Sayle <roger at eyesopen dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sun, 13 Feb 2005 16:17:54 +0000
- Subject: Re: [PATCH] PR19917: Calls to weak functions may trap
- References: <Pine.LNX.4.44.0502130555230.27374-100000@www.eyesopen.com>
Roger,
Roger Sayle wrote:
On Sun, 13 Feb 2005, Graham Stott wrote:
I think the real problem is "if (foo)" is being treated as alays true as
evidenced by this "warning: the address of 'foo', will always evaluate as
'true' which is correct for a "non-weak" fn but not correct for a "weak"
fn.
Strangly, I don't get that warning with the full test-case attached to
the PR, because the function in question *is* marked as weak. This is
again on ia64-unknown-linux-gnu. Indeed, the code that generates the
above diagnostic is only emitted when the function isn't weak:
if (TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL
&& !DECL_WEAK (TREE_OPERAND (expr, 0)))
{
/* Common Ada/Pascal programmer's mistake. We always warn
about this since it is so bad. */
warning ("the address of %qD, will always evaluate as %<true%>",
TREE_OPERAND (expr, 0));
return truthvalue_true_node;
}
Perhaps, you're using a reduced test case where "foo" isn't declared
weak and const?
Ugh I used weak qualifier rather than #pragma weak foo
This doesn't appear correct to me. I don't see why a "const weak" fn
should be treated any different to a "const" fn w.r.t may trap.
As you can see, "const" is irrelevant in my patch. However, the
fundamental difference between a weak function and a non-weak function
is that calling a weak function that isn't resolved will/may trap.
Agreed.
As PR19828 shows, there are clearly still serious problems with
GCC tree-ssa-loop-im.c pass inappropriately moving pure and const
functions. For the subset of those that are weak, the issue may
be worked around, by more correctly modelling weak functions in
tree_could_trap_p.
The tree loop code still looks fragial in corner cases.
extern const int foo1(int) __attribute__((const));
#pragma weak foo1
extern const int foo2(int) __attribute__((const));
extern int x;
void bar1()
{
for (;;)
if (foo1)
x = foo1 (4);
}
void bar2()
{
for (;;)
if (foo2)
x = foo2 (4);
}
Here we we end up with two empty loops
.file "fooweak.c"
.text
.p2align 4,,15
.globl bar1
.type bar1, @function
bar1:
movl $foo1, %eax
pushl %ebp
testl %eax, %eax
movl %esp, %ebp
je .L6
.L7:
jmp .L7
.L6:
jmp .L6
.size bar1, .-bar1
.p2align 4,,15
.globl bar2
.type bar2, @function
bar2:
pushl %ebp
movl %esp, %ebp
.L11:
jmp .L11
.size bar2, .-bar2
.weak foo1
.ident "GCC: (GNU) 4.0.0 20050212 (experimental)"
.section .note.GNU-stack,"",@progbits
The store to x is no where to be seen and we never call foo1 or foo2.
My guess is the stores to x have been moved after the loop and then
deleted as unreachable thus making the calls to foo1/foo2 also
dead. I'm not sure if that's all valid.
The end result is also intresting in other ways because we've still
got dead code. The .L6 and .L6 loops could be fused and then the
foo1 test would be redudent
I hope this clarifies why const functions and weak const functions
need to be treated slightly differently in the middle-end.
Yes
Roger
--