зеркало из https://github.com/microsoft/clang-1.git
Local static variables must be available module-wise
as they are accessible in static methods in a class local to the same function. Fixes PR6769. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101756 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a75b71f967
Коммит
65ad5a42cc
|
@ -548,6 +548,12 @@ public:
|
|||
return getStorageClass() <= Register;
|
||||
}
|
||||
|
||||
/// isStaticLocal - Returns tru if a variable with function scope is a
|
||||
/// static local variable.
|
||||
bool isStaticLocal() const {
|
||||
return getStorageClass() == Static && !isFileVarDecl();
|
||||
}
|
||||
|
||||
/// hasExternStorage - Returns true if a variable has extern or
|
||||
/// __private_extern__ storage.
|
||||
bool hasExternalStorage() const {
|
||||
|
|
|
@ -205,6 +205,7 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D,
|
|||
// Store into LocalDeclMap before generating initializer to handle
|
||||
// circular references.
|
||||
DMEntry = GV;
|
||||
CGM.setStaticLocalDeclMap(&D, GV);
|
||||
|
||||
// Make sure to evaluate VLA bounds now so that we have them for later.
|
||||
//
|
||||
|
|
|
@ -1106,6 +1106,8 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
|
|||
bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
|
||||
|
||||
llvm::Value *V = LocalDeclMap[VD];
|
||||
if (!V && VD->isStaticLocal())
|
||||
V = CGM.getStaticLocalDeclMap(VD);
|
||||
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
|
||||
|
||||
Qualifiers Quals = MakeQualifiers(E->getType());
|
||||
|
|
|
@ -133,6 +133,7 @@ class CodeGenModule : public BlockModule {
|
|||
|
||||
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
|
||||
llvm::StringMap<llvm::Constant*> ConstantStringMap;
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> StaticLocalDeclMap;
|
||||
|
||||
/// CXXGlobalInits - Global variables with initializers that need to run
|
||||
/// before main.
|
||||
|
@ -170,6 +171,14 @@ public:
|
|||
/// been configured.
|
||||
bool hasObjCRuntime() { return !!Runtime; }
|
||||
|
||||
llvm::Value *getStaticLocalDeclMap(const VarDecl *VD) {
|
||||
return StaticLocalDeclMap[VD];
|
||||
}
|
||||
void setStaticLocalDeclMap(const VarDecl *D,
|
||||
llvm::GlobalVariable *GV) {
|
||||
StaticLocalDeclMap[D] = GV;
|
||||
}
|
||||
|
||||
CGDebugInfo *getDebugInfo() { return DebugInfo; }
|
||||
ASTContext &getContext() const { return Context; }
|
||||
const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -o %t %s
|
||||
// PR6769
|
||||
|
||||
struct X {
|
||||
static void f();
|
||||
};
|
||||
|
||||
void X::f() {
|
||||
static int *i;
|
||||
{
|
||||
struct Y {
|
||||
static void g() {
|
||||
i = new int();
|
||||
*i = 100;
|
||||
(*i) = (*i) +1;
|
||||
}
|
||||
};
|
||||
(void)Y::g();
|
||||
}
|
||||
(void)i;
|
||||
}
|
Загрузка…
Ссылка в новой задаче