Skip to content

Commit 802cb82

Browse files
committed
Fix type info in CGExprConstant
1 parent e1f42a0 commit 802cb82

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

clang/lib/CodeGen/CGExprConstant.cpp

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,14 +1914,20 @@ namespace {
19141914
/// that normally happen during l-value emission.
19151915
struct ConstantLValue {
19161916
llvm::Constant *Value;
1917+
llvm::Type *ElementTy;
19171918
bool HasOffsetApplied;
19181919

19191920
/*implicit*/ ConstantLValue(llvm::Constant *value,
19201921
bool hasOffsetApplied = false)
1921-
: Value(value), HasOffsetApplied(hasOffsetApplied) {}
1922+
: Value(value), ElementTy(nullptr), HasOffsetApplied(hasOffsetApplied) {}
1923+
1924+
/*implicit*/ ConstantLValue(llvm::Constant *value,
1925+
llvm::Type *elementTy,
1926+
bool hasOffsetApplied = false)
1927+
: Value(value), ElementTy(elementTy), HasOffsetApplied(hasOffsetApplied) {}
19221928

19231929
/*implicit*/ ConstantLValue(ConstantAddress address)
1924-
: ConstantLValue(address.getPointer()) {}
1930+
: ConstantLValue(address.getPointer(), address.getElementType()) {}
19251931
};
19261932

19271933
/// A helper class for emitting constant l-values.
@@ -1961,6 +1967,12 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19611967
ConstantLValue VisitMaterializeTemporaryExpr(
19621968
const MaterializeTemporaryExpr *E);
19631969

1970+
llvm::Type *ConvertBlockType(QualType Ty) {
1971+
if (CGM.getLangOpts().OpenCL)
1972+
return CGM.getGenericBlockLiteralType();
1973+
return CGM.getTypes().ConvertType(Ty);
1974+
}
1975+
19641976
bool hasNonZeroOffset() const {
19651977
return !Value.getLValueOffset().isZero();
19661978
}
@@ -1972,14 +1984,16 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19721984
}
19731985

19741986
/// Apply the value offset to the given constant.
1975-
llvm::Constant *applyOffset(llvm::Constant *C) {
1987+
llvm::Constant *applyOffset(llvm::Constant *C, llvm::Type *BaseElementTy) {
19761988
uint64_t OffsetVal = Value.getLValueOffset().getQuantity();
19771989

19781990
llvm::SmallVector<llvm::Constant*, 4> Indexes;
19791991
Indexes.push_back(llvm::ConstantInt::get(CGM.Int32Ty, 0));
19801992
llvm::Type* DestTy = CGM.getTypes().ConvertTypeForMem(DestType);
19811993
llvm::Type* DestElemTy = nullptr;
1982-
if (DestTy->isPointerTy())
1994+
if (isa<BlockPointerType>(DestType.getCanonicalType().getTypePtr()))
1995+
DestElemTy = ConvertBlockType(DestType->getPointeeType());
1996+
else if (DestTy->isPointerTy())
19831997
DestElemTy = CGM.getTypes().ConvertTypeForMem(DestType->getPointeeType());
19841998
QualType CurType;
19851999
const APValue::LValueBase &base = Value.getLValueBase();
@@ -1990,13 +2004,19 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
19902004
else
19912005
CurType = base.getTypeInfoType();
19922006

1993-
llvm::Type* CurrentType = CGM.getTypes().ConvertTypeForMem(CurType);
1994-
llvm::Type* CElementType = CurrentType;
2007+
llvm::Type* CurrentType = BaseElementTy;
19952008

1996-
if (!C->getType()->isOpaquePointerTy())
2009+
if (!CurrentType)
2010+
CurrentType = CGM.getTypes().ConvertTypeForMem(CurType);
2011+
2012+
if (C->getType()->isOpaquePointerTy())
2013+
CurrentType = nullptr;
2014+
else
19972015
assert(CurrentType == C->getType()->getNonOpaquePointerElementType());
19982016

1999-
if(Value.hasLValuePath()) {
2017+
llvm::Type* CElementType = CurrentType;
2018+
2019+
if(Value.hasLValuePath() && CGM.getTypes().ConvertTypeForMem(CurType) == CurrentType) {
20002020
ArrayRef<APValue::LValuePathEntry> Path = Value.getLValuePath();
20012021
for (unsigned I = 0; I != Path.size(); ++I) {
20022022
if (const RecordType* CurClass = CurType->getAs<RecordType>()) {
@@ -2043,7 +2063,7 @@ class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
20432063
Indexes.back() = llvm::ConstantInt::get(CGM.Int32Ty, cast<llvm::ConstantInt>(Indexes.back())->getZExtValue()+1);
20442064
}
20452065
OffsetVal = 0;
2046-
} else {
2066+
} else if (CurrentType) {
20472067
// Try to build a naturally looking GEP from the returned expression to the
20482068
// required type
20492069
while(DestTy->isPointerTy() && (OffsetVal || CurrentType!=DestElemTy))
@@ -2132,7 +2152,7 @@ llvm::Constant *ConstantLValueEmitter::tryEmit() {
21322152

21332153
// Apply the offset if necessary and not already done.
21342154
if (!result.HasOffsetApplied) {
2135-
value = applyOffset(value);
2155+
value = applyOffset(value, result.ElementTy);
21362156
}
21372157

21382158
// Convert to the appropriate type; this could be an lvalue for
@@ -2279,7 +2299,7 @@ ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) {
22792299
llvm::Constant *Ptr = Emitter.CGF->GetAddrOfLabel(E->getLabel());
22802300
Ptr = llvm::ConstantExpr::getBitCast(Ptr,
22812301
CGM.getTypes().ConvertType(E->getType()));
2282-
return Ptr;
2302+
return ConstantLValue(Ptr, CGM.getTypes().ConvertTypeForMem(E->getType()->getPointeeType()));
22832303
}
22842304

22852305
ConstantLValue
@@ -2309,7 +2329,7 @@ ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *E) {
23092329
else
23102330
functionName = "global";
23112331

2312-
return CGM.GetAddrOfGlobalBlock(E, functionName);
2332+
return ConstantLValue(CGM.GetAddrOfGlobalBlock(E, functionName), ConvertBlockType(E->getType()->getPointeeType()));
23132333
}
23142334

23152335
ConstantLValue

0 commit comments

Comments
 (0)