r314047. On 22 September 2017 at 16:36, Richard Smith <rich...@metafoo.co.uk> wrote:
> Investigating... > > > On 22 September 2017 at 15:58, Vitaly Buka via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> 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@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.c >>> pp?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/Itaniu >>> mMangle.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/d >>> r11xx.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/CodeGenCX >>> X/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/l >>> inkage2.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/u >>> ndefined-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@-3 {{here}} >>> + // expected-note@-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@-3 {{non-type template argument referring to >>> function 'f' with internal linkage}} >>> + // expected-warning@-3 {{non-type template argument referring to >>> function 'f' with internal linkage}} >>> +#endif >>> } >>> } >>> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits