Bug 33437 - potentially valid construct rejected
Summary: potentially valid construct rejected
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2007-09-14 15:24 UTC by jbeulich
Modified: 2021-08-10 08:04 UTC (History)
1 user (show)

See Also:
Host:
Target: x86_64-*-*
Build:
Known to work:
Known to fail: 4.0.1, 4.3.0, 4.4.0
Last reconfirmed: 2008-11-15 00:43:49


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jbeulich 2007-09-14 15:24:56 UTC
extern char x[] __attribute__((__weak__));
int i = (long)x;

results in 'initializer element is not computable at load time'. However, the compiler really can't know this, as x may be either zero (since it's weak) or may be used as C-level place holder for an assembler/linker defined absolute symbol. While emitting a warning here (that should have a control for suppressing) seems appropriate, failing the compilation isn't - that decision should be left to the assembler (in case the target doesn't have an appropriately sized relocation type) or the linker.
Comment 1 Andrew Pinski 2008-11-15 00:43:49 UTC
This works for me with PPC both 32bit and 64bit but fails with 64bit i686 and works with 32bit x86.
Comment 2 Andrew Pinski 2021-08-09 04:58:15 UTC
This is not a valid C.  That is (int)(long)x where sizeof(long)!=sizeof(int)!=sizeof(void*) the linker might not know the value at link time and therefor will need a runtime relocation and then it might not load at load time as the value would have gotten truncated.
Comment 3 jbeulich 2021-08-10 08:04:26 UTC
(In reply to Andrew Pinski from comment #2)
> This is not a valid C.

As per "All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals."

long l = (long)x;

then either similarly isn't (yet the compiler accepts it), or both are (which is my reading of the sentence, albeit further restrictions make this invalid). Plus if it was strictly invalid, then why would a PPC compiler accept it (as you've said yourself many years ago)?

It was for a reason that I did say  "potentially" in the title. Without knowing what "x" is and what relocation types a target has, the compiler has no justification to say "initializer element is not computable at load time". It might use "may", but then it would still be overly limiting. As said in the original description, "x" may simply stand for a small constant value, which C does not allow to access any (meaningfully) other way than by expressing through either an array (as in the example) or by using the address operator in the initialization.

>  That is (int)(long)x where
> sizeof(long)!=sizeof(int)!=sizeof(void*) the linker might not know the value
> at link time and therefor will need a runtime relocation and then it might
> not load at load time as the value would have gotten truncated.

Hence it should be the assembler's job to determine whether a suitable relocation type is available and the (static and/or dynamic) linker's job to detect and report truncation / overflow. This is not the least because later the standard also says "An implementation may accept other forms of constant expressions."