This is the mail archive of the 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]

Re: [PATCH] PR19917: Calls to weak functions may trap


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"

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:

    && !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.


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
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"
        .p2align 4,,15
.globl bar1
        .type   bar1, @function
        movl    $foo1, %eax
        pushl   %ebp
        testl   %eax, %eax
        movl    %esp, %ebp
        je      .L6
        jmp     .L7
        jmp     .L6
        .size   bar1, .-bar1
        .p2align 4,,15
.globl bar2
        .type   bar2, @function
        pushl   %ebp
        movl    %esp, %ebp
        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.

Roger --

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