Open Quuxplusone opened 10 years ago
Bugzilla Link | PR18552 |
Status | NEW |
Importance | P normal |
Reported by | Mitsuru Kariya (kariya_mitsuru@hotmail.com) |
Reported on | 2014-01-19 23:51:52 -0800 |
Last modified on | 2015-12-04 08:47:27 -0800 |
Version | unspecified |
Hardware | All All |
CC | dgregor@apple.com, llvm-bugs@lists.llvm.org, rafael@espindo.la, richard-llvm@metafoo.co.uk, stephan.bergmann.secondary@googlemail.com |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
Per the current resolution of http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426, we should reject this code. (Per the former resolution, the example has undefined behavior.)
Oh... I cannot understand why the issue #426 is disregarded.
In addition, I found 3.3.1 p4's note.
I think that it considers main.cc as ill-formed because #1 (has internal
linkage) and #3 (has external linkage) refer to the different entities (3.5 p9)
but has same name in a single declarative region (global namespace).
How about the sample code below?
ICBW, I think that the following sample code is compiled incorrectly with clang
3.4 or later.
#include <iostream>
namespace NS {
int i = 1; // #1 has external linkage
}
static int i = 2; // #2 has internal linkage
int main()
{
using NS::i; // It refers to #1, has external linkage.
//extern int i;
std::cout << i << std::endl; // It refers to #1, of course.
{
extern int i; // I think it should refer to #1,
std::cout << i << std::endl; // but it refers to #2.
}
}
Acoording to 7.3.3 p1, a using-declaration introduces a name as a synomym.
And, according to 3.5 p6, if an declaration is visible and the declared entity
has a linkage, an "extern" declaration refers to the entity, and it only
ignores entities declared outside the innermost enclosing namespace scope.
NS::i has external linkage, So I think that the "extern int i;" should refer to
#1.
FYI, if a comment "//extern int i;" is uncommented, it refers to #1.
http://melpon.org/wandbox/permlink/vOM0nOdK36djcCHY
Some random related findings:
* For the related case of
static int i;
struct S {
int i;
static int f() {
extern int i;
return i;
}
};
int main() { return S::f(); }
Clang does reference an external var.
* For the original example from comment 0, behaviour of at least Clang 3.2 and
3.3 was to reference an external var, only since 3.4 it references the static
var. (But for the above struct-based example, behaviour has consistently been
the same ever since at least 3.2.)