Discussion:
ARM and __attribute__ long_call error
Jani Monoses
2005-06-07 15:08:07 UTC
Permalink
Hello

trying to compile the following simple source file using arm-elf-gcc 4.0

void pig(void) __attribute__ ((long_call));
void pig(void)
{
}

yields:

error: conflicting types for 'pig'
error: previous declaration of 'pig' was here

The same with gcc3.3. With other function attributes (isr, section, naked etc.) it works fine.

Aren't attributes supposed to be part of the functin declaration only? What am I missing?
For now I am passing -mlong-call on the command line but with that I cannot get the
granularity I want as with __attribute__.

thanks
Jani
Richard Earnshaw
2005-06-07 16:12:11 UTC
Permalink
Post by Jani Monoses
Hello
trying to compile the following simple source file using arm-elf-gcc 4.0
void pig(void) __attribute__ ((long_call));
void pig(void)
{
}
error: conflicting types for 'pig'
error: previous declaration of 'pig' was here
Yes, that's the way it's currently coded.

The problem, it seems to me, is that we want to fault:

void pig(void) __attribute__ ((long_call));
...
void pig(void);

and

void pig(void);
...
void pig(void) __attribute__((long_call));

both of which would be potentially problematical (which do we believe?)
from the case that you have. AFAICT there is nothing on the types
passed into the back-end to distinguish a declaration from a definition
in this context.
Post by Jani Monoses
The same with gcc3.3. With other function attributes (isr, section, naked etc.) it works fine.
Looking at the code suggests isr should be strictly enforced too.

R.
Jani Monoses
2005-06-08 10:11:22 UTC
Permalink
Post by Richard Earnshaw
Post by Jani Monoses
void pig(void) __attribute__ ((long_call));
void pig(void)
{
}
Yes, that's the way it's currently coded.
void pig(void) __attribute__ ((long_call));
...
void pig(void);
and
void pig(void);
...
void pig(void) __attribute__((long_call));
both of which would be potentially problematical (which do we believe?)
from the case that you have. AFAICT there is nothing on the types
passed into the back-end to distinguish a declaration from a definition
in this context.
The cases you mention are two declarations right? My example had the attribute on the
declaration and not on the definition just like with the other attribute types.
I suppose your explanation went way over my head, since I still don't understand what is
different with the long-call attribute that the same approach which works with other
function attributes yields an error in this case.
Is there anything tricky that prevents an easy implementation?

thanks
Jani
Richard Earnshaw
2005-06-08 10:28:11 UTC
Permalink
Post by Jani Monoses
Post by Richard Earnshaw
Post by Jani Monoses
void pig(void) __attribute__ ((long_call));
void pig(void)
{
}
Yes, that's the way it's currently coded.
void pig(void) __attribute__ ((long_call));
...
void pig(void);
and
void pig(void);
...
void pig(void) __attribute__((long_call));
both of which would be potentially problematical (which do we believe?)
from the case that you have. AFAICT there is nothing on the types
passed into the back-end to distinguish a declaration from a definition
in this context.
The cases you mention are two declarations right?
Erm, yes (though I'd intended to write the second example as a
declaration followed by a definition).
Post by Jani Monoses
My example had the attribute on the
declaration and not on the definition just like with the other attribute types.
I suppose your explanation went way over my head, since I still don't understand what is
different with the long-call attribute that the same approach which works with other
function attributes yields an error in this case.
Is there anything tricky that prevents an easy implementation?
Yes, internally the routine that's doing the comparison can't
distinguish declarations from definitions. We need to diagnose
conflicting declarations, and also where the *definition* is attributed
but the declaration was not.

We could relax the rules to allow your case, but only at the expense of
losing checking for the above scenarios. I'm not convinced that is a
good trade-off.

R.
Jani Monoses
2005-06-08 10:51:22 UTC
Permalink
Post by Richard Earnshaw
Post by Jani Monoses
Is there anything tricky that prevents an easy implementation?
Yes, internally the routine that's doing the comparison can't
distinguish declarations from definitions. We need to diagnose
Is the routine arm_comp_type_attributes() in gcc/config/arm/arm.c by any chance?
Post by Richard Earnshaw
conflicting declarations, and also where the *definition* is attributed
but the declaration was not.
How can you attribute the definition? This results in syntax error.

void pig(void) __attribute__ ((long_call)
{
}
Post by Richard Earnshaw
We could relax the rules to allow your case, but only at the expense of
losing checking for the above scenarios. I'm not convinced that is a
good trade-off.
I don't need changes to the existing rules, just to find out how attribute long_call is
_supposed_ to be used :). I see something similar exists for the RS6000 back-end.
Do these not work but are added and waiting for a future implementation?

thanks
Jani
Richard Earnshaw
2005-06-08 10:57:48 UTC
Permalink
Post by Jani Monoses
Post by Richard Earnshaw
Post by Jani Monoses
Is there anything tricky that prevents an easy implementation?
Yes, internally the routine that's doing the comparison can't
distinguish declarations from definitions. We need to diagnose
Is the routine arm_comp_type_attributes() in gcc/config/arm/arm.c by any chance?
Yes.
Post by Jani Monoses
Post by Richard Earnshaw
conflicting declarations, and also where the *definition* is attributed
but the declaration was not.
How can you attribute the definition? This results in syntax error.
void pig(void) __attribute__ ((long_call)
{
}
void __attribute__ ((long_call)) pig(void)
{
}

R.
Jani Monoses
2005-06-08 11:22:00 UTC
Permalink
Post by Richard Earnshaw
void __attribute__ ((long_call)) pig(void)
{
}
Ok thanks, with such change to the definition the file compiles.
I didn't know one can attribute definitions too, and info gcc says:

"
The keyword `__attribute__' allows you to specify special attributes
when making a declaration.
"

So I supposed that for any function that has an attribute you need an explicit function
declaration stating that, and then the definition as usual.

Jani

Loading...