This doesn't affect our code generation in any material way -- we already give such declarations internal linkage from a codegen perspective -- but it has some subtle effects on code validity. We suppress the 'L' (internal linkage) marker for mangled names in anonymous namespaces, because it is redundant (the information is already carried by the namespace); this deviates from GCC's behavior if a variable or function in an anonymous namespace is redundantly declared 'static' (where GCC does include the 'L'), but GCC's behavior is incoherent because such a declaration can be validly declared with or without the 'static'. We still deviate from the standard in one regard here: extern "C" declarations in anonymous namespaces are still granted external linkage. Changing those does not appear to have been an intentional consequence of the standard change in DR1113. llvm-svn: 314037
31 lines
1.2 KiB
C++
31 lines
1.2 KiB
C++
// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
// RUN: %clang_cc1 -std=c++2a %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
|
|
|
|
namespace dr1113 { // dr1113: partial
|
|
namespace named {
|
|
extern int a; // expected-note {{previous}}
|
|
static int a; // expected-error {{static declaration of 'a' follows non-static}}
|
|
}
|
|
namespace {
|
|
extern int a;
|
|
static int a; // ok, both declarations have internal linkage
|
|
int b = a;
|
|
}
|
|
|
|
// FIXME: Per DR1113 and DR4, this is ill-formed due to ambiguity: the second
|
|
// 'f' has internal linkage, and so does not have C language linkage, so is
|
|
// not a redeclaration of the first 'f'.
|
|
//
|
|
// To avoid a breaking change here, Clang ignores the "internal linkage" effect
|
|
// of anonymous namespaces on declarations declared within an 'extern "C"'
|
|
// linkage-specification.
|
|
extern "C" void f();
|
|
namespace {
|
|
extern "C" void f();
|
|
}
|
|
void g() { f(); }
|
|
}
|