зеркало из https://github.com/microsoft/clang.git
Fix the rest of PR9316 along with some other bugs spotted by inspection.
I tried to add test cases for these, but I can't because variables aren't warned on the way functions are and the codegen layer appears to use different logic for determining that 'a' and 'g' in the test case should receive C mangling. I've included the test so that if we ever switch the codegen layer to use these functions, we won't regress due to latent bugs. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126453 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b43e8ad893
Коммит
10aad449df
|
@ -708,7 +708,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
|
|||
// external linkage.
|
||||
if (D->getLexicalDeclContext()->isFunctionOrMethod()) {
|
||||
if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
|
||||
if (Function->isInAnonymousNamespace())
|
||||
if (Function->isInAnonymousNamespace() && !Function->isExternC())
|
||||
return LinkageInfo::uniqueExternal();
|
||||
|
||||
LinkageInfo LV;
|
||||
|
@ -729,7 +729,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D, LVFlags Flags) {
|
|||
if (const VarDecl *Var = dyn_cast<VarDecl>(D))
|
||||
if (Var->getStorageClass() == SC_Extern ||
|
||||
Var->getStorageClass() == SC_PrivateExtern) {
|
||||
if (Var->isInAnonymousNamespace())
|
||||
if (Var->isInAnonymousNamespace() && !Var->isExternC())
|
||||
return LinkageInfo::uniqueExternal();
|
||||
|
||||
LinkageInfo LV;
|
||||
|
@ -1041,8 +1041,11 @@ bool VarDecl::isExternC() const {
|
|||
getStorageClass() != SC_Static) ||
|
||||
(getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
|
||||
|
||||
for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
|
||||
DC = DC->getParent()) {
|
||||
const DeclContext *DC = getDeclContext();
|
||||
if (DC->isFunctionOrMethod())
|
||||
return false;
|
||||
|
||||
for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
|
||||
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
|
||||
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
|
||||
return getStorageClass() != SC_Static;
|
||||
|
@ -1050,8 +1053,6 @@ bool VarDecl::isExternC() const {
|
|||
break;
|
||||
}
|
||||
|
||||
if (DC->isFunctionOrMethod())
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1367,8 +1368,11 @@ bool FunctionDecl::isExternC() const {
|
|||
if (!Context.getLangOptions().CPlusPlus)
|
||||
return getStorageClass() != SC_Static && !getAttr<OverloadableAttr>();
|
||||
|
||||
for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
|
||||
DC = DC->getParent()) {
|
||||
const DeclContext *DC = getDeclContext();
|
||||
if (DC->isRecord())
|
||||
return false;
|
||||
|
||||
for (; !DC->isTranslationUnit(); DC = DC->getParent()) {
|
||||
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
|
||||
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
|
||||
return getStorageClass() != SC_Static &&
|
||||
|
@ -1376,9 +1380,6 @@ bool FunctionDecl::isExternC() const {
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
if (DC->isRecord())
|
||||
break;
|
||||
}
|
||||
|
||||
return isMain();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
// compared against the earlier cached value. If we had a way of
|
||||
// testing linkage directly in Sema, that would be better.
|
||||
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -Werror -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
// PR8926
|
||||
namespace test0 {
|
||||
|
@ -69,5 +69,28 @@ namespace {
|
|||
extern "C" void test4(void) {}
|
||||
}
|
||||
|
||||
// PR9316: Ensure that even non-namespace-scope function declarations in
|
||||
// a C declaration context respect that over the anonymous namespace.
|
||||
extern "C" {
|
||||
namespace {
|
||||
struct X {
|
||||
int f() {
|
||||
extern int g();
|
||||
extern int a;
|
||||
|
||||
// Test both for mangling in the code generation and warnings from use
|
||||
// of internal, undefined names via -Werror.
|
||||
// CHECK: call i32 @g(
|
||||
// CHECK: load i32* @a,
|
||||
return g() + a;
|
||||
}
|
||||
};
|
||||
}
|
||||
// Force the above function to be emitted by codegen.
|
||||
int test(X& x) {
|
||||
return x.f();
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: define linkonce_odr i8* @_ZN5test21A1BILj0EE3fooEv(
|
||||
// CHECK: define linkonce_odr i8* @_ZN5test11A3fooILj0EEEPvv(
|
||||
|
|
Загрузка…
Ссылка в новой задаче