diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2011-11-16 00:42:57 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2011-11-16 00:42:57 +0000 |
commit | 2f77b3d57031ded0de2b7b977fb63b4660f82624 (patch) | |
tree | 69c8f2e92274b61cbcc8583fcbb2ad2b3f725d81 /lib/CodeGen/CGExpr.cpp | |
parent | 1432569f88c6da4da902df7571621f3ea3f76596 (diff) |
Fix a bunch of really nasty bugs in how we compute alignment for reference lvalues. PR11376.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144745 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0b6195dc79..a35bb5f711 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1319,14 +1319,19 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, "Var decl must have external storage or be a file var decl!"); llvm::Value *V = CGF.CGM.GetAddrOfGlobalVar(VD); - if (VD->getType()->isReferenceType()) - V = CGF.Builder.CreateLoad(V); - - V = EmitBitCastOfLValueToProperType(CGF, V, - CGF.getTypes().ConvertTypeForMem(E->getType())); - + llvm::Type *RealVarTy = CGF.getTypes().ConvertTypeForMem(VD->getType()); + V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy); unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity(); - LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment); + QualType T = E->getType(); + LValue LV; + if (VD->getType()->isReferenceType()) { + llvm::LoadInst *LI = CGF.Builder.CreateLoad(V); + LI->setAlignment(Alignment); + V = LI; + LV = CGF.MakeNaturalAlignAddrLValue(V, T); + } else { + LV = CGF.MakeAddrLValue(V, E->getType(), Alignment); + } setObjCGCLValueClass(CGF.getContext(), E, LV); return LV; } @@ -1353,6 +1358,7 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { const NamedDecl *ND = E->getDecl(); unsigned Alignment = getContext().getDeclAlign(ND).getQuantity(); + QualType T = E->getType(); if (ND->hasAttr<WeakRefAttr>()) { const ValueDecl *VD = cast<ValueDecl>(ND); @@ -1377,14 +1383,17 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { if (VD->hasAttr<BlocksAttr>()) V = BuildBlockByrefAddress(V, VD); - - if (VD->getType()->isReferenceType()) - V = Builder.CreateLoad(V); - V = EmitBitCastOfLValueToProperType(*this, V, - getTypes().ConvertTypeForMem(E->getType())); + LValue LV; + if (VD->getType()->isReferenceType()) { + llvm::LoadInst *LI = Builder.CreateLoad(V); + LI->setAlignment(Alignment); + V = LI; + LV = MakeNaturalAlignAddrLValue(V, T); + } else { + LV = MakeAddrLValue(V, T, Alignment); + } - LValue LV = MakeAddrLValue(V, E->getType(), Alignment); if (NonGCable) { LV.getQuals().removeObjCGCAttr(); LV.setNonGC(true); @@ -1843,6 +1852,7 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, const RecordDecl *rec = field->getParent(); QualType type = field->getType(); + unsigned alignment = getContext().getDeclAlign(field).getQuantity(); bool mayAlias = rec->hasAttr<MayAliasAttr>(); @@ -1859,6 +1869,7 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, if (const ReferenceType *refType = type->getAs<ReferenceType>()) { llvm::LoadInst *load = Builder.CreateLoad(addr, "ref"); if (cvr & Qualifiers::Volatile) load->setVolatile(true); + load->setAlignment(alignment); if (CGM.shouldUseTBAA()) { llvm::MDNode *tbaa; @@ -1872,6 +1883,10 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, addr = load; mayAlias = false; type = refType->getPointeeType(); + if (type->isIncompleteType()) + alignment = 0; + else + alignment = getContext().getTypeAlignInChars(type).getQuantity(); cvr = 0; // qualifiers don't recursively apply to referencee } } @@ -1887,7 +1902,6 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr, if (field->hasAttr<AnnotateAttr>()) addr = EmitFieldAnnotations(field, addr); - unsigned alignment = getContext().getDeclAlign(field).getQuantity(); LValue LV = MakeAddrLValue(addr, type, alignment); LV.getQuals().addCVRQualifiers(cvr); |