r360637 - PR41817: Fix regression in r359260 that caused the MS compatibility
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Tue May 14 03:09:05 PDT 2019
Actually, we didn't notice r359260 in Chromium, however this one
(r360637) caused Clang to start asserting during our builds
(https://bugs.chromium.org/p/chromium/issues/detail?id=962840), here's
a reduced test case:
--
extern int a;
static int *use1 = &a;
int **use2 = &use1;
static int a = 0;
--
$ clang.bad -cc1 -triple i386-pc-windows-msvc19.11.0 -emit-obj
-fms-extensions /tmp/a.cc
clang.bad: /work/llvm.monorepo/clang/lib/AST/Decl.cpp:1494:
clang::LinkageInfo clang::LinkageComputer::getLVForDecl(const
clang::NamedDecl*, clang::LVComputationKind): Assertion
`D->getCachedLinkage() == LV.getLinkage()' failed.
I've reverted this one in r360657 in the meantime.
From: Richard Smith via cfe-commits <cfe-commits at lists.llvm.org>
Date: Tue, May 14, 2019 at 2:24 AM
To: <cfe-commits at lists.llvm.org>
> Author: rsmith
> Date: Mon May 13 17:27:16 2019
> New Revision: 360637
>
> URL: http://llvm.org/viewvc/llvm-project?rev=360637&view=rev
> Log:
> PR41817: Fix regression in r359260 that caused the MS compatibility
> extension allowing a "static" declaration to follow an "extern"
> declaration to stop working.
>
> Added:
> cfe/trunk/test/CodeGen/ms-compat-extern-static.c
> Modified:
> cfe/trunk/lib/AST/Decl.cpp
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=360637&r1=360636&r2=360637&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Mon May 13 17:27:16 2019
> @@ -613,12 +613,41 @@ static LinkageInfo getExternalLinkageFor
> static StorageClass getStorageClass(const Decl *D) {
> if (auto *TD = dyn_cast<TemplateDecl>(D))
> D = TD->getTemplatedDecl();
> - if (D) {
> - if (auto *VD = dyn_cast<VarDecl>(D))
> - return VD->getStorageClass();
> - if (auto *FD = dyn_cast<FunctionDecl>(D))
> - return FD->getStorageClass();
> + if (!D)
> + return SC_None;
> +
> + if (auto *VD = dyn_cast<VarDecl>(D)) {
> + // Generally, the storage class is determined by the first declaration.
> + auto SC = VD->getCanonicalDecl()->getStorageClass();
> +
> + // ... except that MSVC permits an 'extern' declaration to be redeclared
> + // 'static' as an extension.
> + if (SC == SC_Extern) {
> + for (auto *Redecl : VD->redecls()) {
> + if (Redecl->getStorageClass() == SC_Static)
> + return SC_Static;
> + if (Redecl->getStorageClass() != SC_Extern &&
> + !Redecl->isLocalExternDecl() && !Redecl->getFriendObjectKind())
> + break;
> + }
> + }
> + return SC;
> }
> +
> + if (auto *FD = dyn_cast<FunctionDecl>(D)) {
> + auto SC = FD->getCanonicalDecl()->getStorageClass();
> + if (SC == SC_Extern) {
> + for (auto *Redecl : FD->redecls()) {
> + if (Redecl->getStorageClass() == SC_Static)
> + return SC_Static;
> + if (Redecl->getStorageClass() != SC_Extern &&
> + !Redecl->isLocalExternDecl() && !Redecl->getFriendObjectKind())
> + break;
> + }
> + }
> + return SC;
> + }
> +
> return SC_None;
> }
>
> @@ -634,7 +663,7 @@ LinkageComputer::getLVForNamespaceScopeD
> // A name having namespace scope (3.3.6) has internal linkage if it
> // is the name of
>
> - if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
> + if (getStorageClass(D) == SC_Static) {
> // - a variable, variable template, function, or function template
> // that is explicitly declared static; or
> // (This bullet corresponds to C99 6.2.2p3.)
>
> Added: cfe/trunk/test/CodeGen/ms-compat-extern-static.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/ms-compat-extern-static.c?rev=360637&view=auto
> ==============================================================================
> --- cfe/trunk/test/CodeGen/ms-compat-extern-static.c (added)
> +++ cfe/trunk/test/CodeGen/ms-compat-extern-static.c Mon May 13 17:27:16 2019
> @@ -0,0 +1,11 @@
> +// RUN: %clang_cc1 -emit-llvm %s -o - -fms-extensions -triple x86_64-windows | FileCheck %s
> +
> +// CHECK: @n = internal global i32 1
> +extern int n;
> +static int n = 1;
> +int *use = &n;
> +
> +// CHECK: define internal void @f(
> +extern void f();
> +static void f() {}
> +void g() { return f(); }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list