|
16 | 16 | #include "MemberPointer.h" |
17 | 17 | #include "PrimType.h" |
18 | 18 | #include "Record.h" |
| 19 | +#include "clang/AST/ExprCXX.h" |
19 | 20 | #include "clang/AST/RecordLayout.h" |
20 | 21 |
|
21 | 22 | using namespace clang; |
@@ -155,12 +156,32 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const { |
155 | 156 | APValue::LValueBase Base; |
156 | 157 | if (const auto *VD = Desc->asValueDecl()) |
157 | 158 | Base = VD; |
158 | | - else if (const auto *E = Desc->asExpr()) |
159 | | - Base = E; |
160 | | - else |
| 159 | + else if (const auto *E = Desc->asExpr()) { |
| 160 | + // Create a DynamicAlloc base of the right type. |
| 161 | + if (const auto *NewExpr = dyn_cast<CXXNewExpr>(E)) { |
| 162 | + QualType AllocatedType; |
| 163 | + if (NewExpr->isArray()) { |
| 164 | + assert(Desc->isArray()); |
| 165 | + APInt ArraySize(64, static_cast<uint64_t>(Desc->getNumElems()), |
| 166 | + /*IsSigned=*/false); |
| 167 | + AllocatedType = |
| 168 | + ASTCtx.getConstantArrayType(NewExpr->getAllocatedType(), ArraySize, |
| 169 | + nullptr, ArraySizeModifier::Normal, 0); |
| 170 | + } else { |
| 171 | + AllocatedType = NewExpr->getAllocatedType(); |
| 172 | + } |
| 173 | + // FIXME: Suboptimal counting of dynamic allocations. Move this to Context |
| 174 | + // or InterpState? |
| 175 | + static int ReportedDynamicAllocs = 0; |
| 176 | + DynamicAllocLValue DA(ReportedDynamicAllocs++); |
| 177 | + Base = APValue::LValueBase::getDynamicAlloc(DA, AllocatedType); |
| 178 | + } else { |
| 179 | + Base = E; |
| 180 | + } |
| 181 | + } else |
161 | 182 | llvm_unreachable("Invalid allocation type"); |
162 | 183 |
|
163 | | - if (isUnknownSizeArray() || Desc->asExpr()) |
| 184 | + if (isUnknownSizeArray()) |
164 | 185 | return APValue(Base, CharUnits::Zero(), Path, |
165 | 186 | /*IsOnePastEnd=*/isOnePastEnd(), /*IsNullPtr=*/false); |
166 | 187 |
|
|
0 commit comments