Recent minor C regression (maybe)

The following dubious (IMHO) code no longer compiles, though it does in
other popular compilers.

static void a(void);
extern void a();
static void a(void) {}

(In this specific case the code is partly generated: the extern
declaration is generated and the static ones are hand generated.)

I'm guessing this is caused by reverting the reversion of r178663 (it
touches what looks like the right bit of code and it's dated April 3, so
the timing's about right), but I haven't checked.

(Not sure whether the code should be legal. I'd guess we don't have the
only instance of this kind of thing.)

My bug. Looking at it.

Thanks for reporting it!

Cheers,
Rafael

The following dubious (IMHO) code no longer compiles, though it does in
other popular compilers.

static void a(void);
extern void a();
static void a(void) {}

(In this specific case the code is partly generated: the extern
declaration is generated and the static ones are hand generated.)

I’m guessing this is caused by reverting the reversion of r178663 (it
touches what looks like the right bit of code and it’s dated April 3, so
the timing’s about right), but I haven’t checked.

(Not sure whether the code should be legal. I’d guess we don’t have the
only instance of this kind of thing.)

This does seem like it should be legal, per C11 6.2.2p4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.

C++11 seems to get this implicitly from its own linkage rules [basic.link]p3:

A name having namespace scope (3.3.6) has internal linkage if it is the name of

  • a variable, function or function template that is explicitly declared static…

Please file a bug (and for bonus points, assign it to Rafael.)

Jordan

The following dubious (IMHO) code no longer compiles, though it does in
other popular compilers.

static void a(void);
extern void a();
static void a(void) {}

(In this specific case the code is partly generated: the extern
declaration is generated and the static ones are hand generated.)

I’m guessing this is caused by reverting the reversion of r178663 (it
touches what looks like the right bit of code and it’s dated April 3, so
the timing’s about right), but I haven’t checked.

(Not sure whether the code should be legal. I’d guess we don’t have the
only instance of this kind of thing.)

This does seem like it should be legal, per C11 6.2.2p4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.

C++11 seems to get this implicitly from its own linkage rules [basic.link]p3:

A name having namespace scope (3.3.6) has internal linkage if it is the name of

  • a variable, function or function template that is explicitly declared static…

Please file a bug (and for bonus points, assign it to Rafael.)

Jordan