r314037 - DR1113: anonymous namespaces formally give their contents internal linkage.
Vitaly Buka via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 22 15:58:21 PDT 2017
This breaks check-clang-tools
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/12310/steps/test/logs/stdio
On Fri, Sep 22, 2017 at 3:21 PM, Richard Smith via cfe-commits <
cfe-commits at lists.llvm.org> wrote:
> Author: rsmith
> Date: Fri Sep 22 15:21:44 2017
> New Revision: 314037
>
> URL: http://llvm.org/viewvc/llvm-project?rev=314037&view=rev
> Log:
> DR1113: anonymous namespaces formally give their contents internal linkage.
>
> 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.
>
> Added:
> cfe/trunk/test/CXX/drs/dr11xx.cpp
> Modified:
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/AST/ItaniumMangle.cpp
> cfe/trunk/test/CXX/basic/basic.link/p8.cpp
> cfe/trunk/test/CodeGenCXX/anonymous-namespaces.cpp
> cfe/trunk/test/SemaCXX/linkage2.cpp
> cfe/trunk/test/SemaCXX/undefined-internal.cpp
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> Decl.cpp?rev=314037&r1=314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Fri Sep 22 15:21:44 2017
> @@ -619,16 +619,16 @@ LinkageComputer::getLVForNamespaceScopeD
> if (D->isInAnonymousNamespace()) {
> const auto *Var = dyn_cast<VarDecl>(D);
> const auto *Func = dyn_cast<FunctionDecl>(D);
> - // FIXME: In C++11 onwards, anonymous namespaces should give decls
> - // within them (including those inside extern "C" contexts) internal
> - // linkage, not unique external linkage:
> + // FIXME: The check for extern "C" here is not justified by the
> standard
> + // wording, but we retain it from the pre-DR1113 model to avoid
> breaking
> + // code.
> //
> // C++11 [basic.link]p4:
> // An unnamed namespace or a namespace declared directly or
> indirectly
> // within an unnamed namespace has internal linkage.
> if ((!Var || !isFirstInExternCContext(Var)) &&
> (!Func || !isFirstInExternCContext(Func)))
> - return LinkageInfo::uniqueExternal();
> + return getInternalLinkageFor(D);
> }
>
> // Set up the defaults.
> @@ -1130,7 +1130,7 @@ LinkageInfo LinkageComputer::getLVForLoc
> if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
> if (Function->isInAnonymousNamespace() &&
> !Function->isInExternCContext())
> - return LinkageInfo::uniqueExternal();
> + return getInternalLinkageFor(Function);
>
> // This is a "void f();" which got merged with a file static.
> if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
> @@ -1153,7 +1153,7 @@ LinkageInfo LinkageComputer::getLVForLoc
> if (const auto *Var = dyn_cast<VarDecl>(D)) {
> if (Var->hasExternalStorage()) {
> if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
> - return LinkageInfo::uniqueExternal();
> + return getInternalLinkageFor(Var);
>
> LinkageInfo LV;
> if (Var->getStorageClass() == SC_PrivateExtern)
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
> ItaniumMangle.cpp?rev=314037&r1=314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Fri Sep 22 15:21:44 2017
> @@ -1287,9 +1287,15 @@ void CXXNameMangler::mangleUnqualifiedNa
> //
> // void test() { extern void foo(); }
> // static void foo();
> + //
> + // Don't bother with the L marker for names in anonymous
> namespaces; the
> + // 12_GLOBAL__N_1 mangling is quite sufficient there, and this
> better
> + // matches GCC anyway, because GCC does not treat anonymous
> namespaces as
> + // implying internal linkage.
> if (ND && ND->getFormalLinkage() == InternalLinkage &&
> !ND->isExternallyVisible() &&
> - getEffectiveDeclContext(ND)->isFileContext())
> + getEffectiveDeclContext(ND)->isFileContext() &&
> + !ND->isInAnonymousNamespace())
> Out << 'L';
>
> auto *FD = dyn_cast<FunctionDecl>(ND);
>
> Modified: cfe/trunk/test/CXX/basic/basic.link/p8.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> basic/basic.link/p8.cpp?rev=314037&r1=314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/basic/basic.link/p8.cpp (original)
> +++ cfe/trunk/test/CXX/basic/basic.link/p8.cpp Fri Sep 22 15:21:44 2017
> @@ -52,6 +52,13 @@ void use_visible_no_linkage() {
> visible_no_linkage3(); // expected-note {{used here}}
> }
>
> +namespace {
> + struct InternalLinkage {};
> +}
> +InternalLinkage internal_linkage(); // expected-error {{used but not
> defined}}
> +void use_internal_linkage() {
> + internal_linkage(); // expected-note {{used here}}
> +}
>
> extern inline int not_defined; // expected-error {{not defined}}
> extern inline int defined_after_use;
>
> Added: cfe/trunk/test/CXX/drs/dr11xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/
> drs/dr11xx.cpp?rev=314037&view=auto
> ============================================================
> ==================
> --- cfe/trunk/test/CXX/drs/dr11xx.cpp (added)
> +++ cfe/trunk/test/CXX/drs/dr11xx.cpp Fri Sep 22 15:21:44 2017
> @@ -0,0 +1,30 @@
> +// 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(); }
> +}
>
> Modified: cfe/trunk/test/CodeGenCXX/anonymous-namespaces.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> CodeGenCXX/anonymous-namespaces.cpp?rev=314037&r1=
> 314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/CodeGenCXX/anonymous-namespaces.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/anonymous-namespaces.cpp Fri Sep 22
> 15:21:44 2017
> @@ -6,7 +6,8 @@ int f();
>
> namespace {
> // CHECK-1: @_ZN12_GLOBAL__N_11bE = internal global i32 0
> - // CHECK-1: @_ZN12_GLOBAL__N_1L1cE = internal global i32 0
> + // CHECK-1: @_ZN12_GLOBAL__N_11cE = internal global i32 0
> + // CHECK-1: @_ZN12_GLOBAL__N_12c2E = internal global i32 0
> // CHECK-1: @_ZN12_GLOBAL__N_11D1dE = internal global i32 0
> // CHECK-1: @_ZN12_GLOBAL__N_11aE = internal global i32 0
> int a = 0;
> @@ -15,6 +16,12 @@ namespace {
>
> static int c = f();
>
> + // Note, we can't use an 'L' mangling for c or c2 (like GCC does) based
> on
> + // the 'static' specifier, because the variable can be redeclared
> without it.
> + extern int c2;
> + int g() { return c2; }
> + static int c2 = f();
> +
> class D {
> static int d;
> };
>
> Modified: cfe/trunk/test/SemaCXX/linkage2.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/linkage2.cpp?rev=314037&r1=314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/linkage2.cpp (original)
> +++ cfe/trunk/test/SemaCXX/linkage2.cpp Fri Sep 22 15:21:44 2017
> @@ -143,9 +143,10 @@ namespace test13 {
> }
>
> namespace test14 {
> + // Anonymous namespace implies internal linkage, so 'static' has no
> effect.
> namespace {
> - void a(void); // expected-note {{previous declaration is here}}
> - static void a(void) {} // expected-error {{static declaration of 'a'
> follows non-static declaration}}
> + void a(void);
> + static void a(void) {}
> }
> }
>
>
> Modified: cfe/trunk/test/SemaCXX/undefined-internal.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/
> SemaCXX/undefined-internal.cpp?rev=314037&r1=314036&r2=314037&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/undefined-internal.cpp (original)
> +++ cfe/trunk/test/SemaCXX/undefined-internal.cpp Fri Sep 22 15:21:44 2017
> @@ -187,6 +187,10 @@ namespace OverloadUse {
> void f();
> void f(int); // expected-warning {{function 'OverloadUse::(anonymous
> namespace)::f' has internal linkage but is not defined}}
> void f(int, int); // expected-warning {{function
> 'OverloadUse::(anonymous namespace)::f' has internal linkage but is not
> defined}}
> +#if __cplusplus < 201103L
> + // expected-note at -3 {{here}}
> + // expected-note at -3 {{here}}
> +#endif
> }
> template<void x()> void t() { x(); }
> template<void x(int)> void t(int*) { x(10); }
> @@ -194,6 +198,10 @@ namespace OverloadUse {
> void g(int n) {
> t<f>(&n); // expected-note {{used here}}
> t<f>(&n, &n); // expected-note {{used here}}
> +#if __cplusplus < 201103L
> + // expected-warning at -3 {{non-type template argument referring to
> function 'f' with internal linkage}}
> + // expected-warning at -3 {{non-type template argument referring to
> function 'f' with internal linkage}}
> +#endif
> }
> }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170922/ce0bcdc6/attachment-0001.html>
More information about the cfe-commits
mailing list