Skip to content

Commit

Permalink
Fix a nondeterminism in the debug info for VLA size expressions.
Browse files Browse the repository at this point in the history
The artificial variable describing the array size is supposed to be
called "__vla_expr", but this was implemented by retrieving the name
of the associated alloca, which isn't a reliable source for the name,
since nonassert compilers may drop names from LLVM IR.

rdar://problem/45924808

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@346542 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
adrian-prantl committed Nov 9, 2018
1 parent 1b6c047 commit df5383b
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 8 deletions.
17 changes: 12 additions & 5 deletions lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,7 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
// For each dimension stores its QualType and corresponding
// size-expression Value.
SmallVector<CodeGenFunction::VlaSizePair, 4> Dimensions;
SmallVector<IdentifierInfo *, 4> VLAExprNames;

// Break down the array into individual dimensions.
QualType Type1D = D.getType();
Expand All @@ -1074,8 +1075,14 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
Dimensions.emplace_back(C, Type1D.getUnqualifiedType());
else {
auto SizeExprAddr = CreateDefaultAlignTempAlloca(
VlaSize.NumElts->getType(), "__vla_expr");
// Generate a locally unique name for the size expression.
Twine Name = Twine("__vla_expr") + Twine(VLAExprCounter++);
SmallString<12> Buffer;
StringRef NameRef = Name.toStringRef(Buffer);
auto &Ident = getContext().Idents.getOwn(NameRef);
VLAExprNames.push_back(&Ident);
auto SizeExprAddr =
CreateDefaultAlignTempAlloca(VlaSize.NumElts->getType(), NameRef);
Builder.CreateStore(VlaSize.NumElts, SizeExprAddr);
Dimensions.emplace_back(SizeExprAddr.getPointer(),
Type1D.getUnqualifiedType());
Expand All @@ -1089,20 +1096,20 @@ void CodeGenFunction::EmitAndRegisterVariableArrayDimensions(
// Register each dimension's size-expression with a DILocalVariable,
// so that it can be used by CGDebugInfo when instantiating a DISubrange
// to describe this array.
unsigned NameIdx = 0;
for (auto &VlaSize : Dimensions) {
llvm::Metadata *MD;
if (auto *C = dyn_cast<llvm::ConstantInt>(VlaSize.NumElts))
MD = llvm::ConstantAsMetadata::get(C);
else {
// Create an artificial VarDecl to generate debug info for.
IdentifierInfo &NameIdent = getContext().Idents.getOwn(
cast<llvm::AllocaInst>(VlaSize.NumElts)->getName());
IdentifierInfo *NameIdent = VLAExprNames[NameIdx++];
auto VlaExprTy = VlaSize.NumElts->getType()->getPointerElementType();
auto QT = getContext().getIntTypeForBitwidth(
VlaExprTy->getScalarSizeInBits(), false);
auto *ArtificialDecl = VarDecl::Create(
getContext(), const_cast<DeclContext *>(D.getDeclContext()),
D.getLocation(), D.getLocation(), &NameIdent, QT,
D.getLocation(), D.getLocation(), NameIdent, QT,
getContext().CreateTypeSourceInfo(QT), SC_Auto);
ArtificialDecl->setImplicit();

Expand Down
2 changes: 2 additions & 0 deletions lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,8 @@ class CodeGenFunction : public CodeGenTypeCache {

private:
CGDebugInfo *DebugInfo;
/// Used to create unique names for artificial VLA size debug info variables.
unsigned VLAExprCounter = 0;
bool DisableDebugInfo = false;

/// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid
Expand Down
4 changes: 2 additions & 2 deletions test/CodeGen/debug-info-vla.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

void testVLAwithSize(int s)
{
// CHECK-DAG: dbg.declare({{.*}} %__vla_expr, metadata ![[VLAEXPR:[0-9]+]]
// CHECK-DAG: dbg.declare({{.*}} %__vla_expr0, metadata ![[VLAEXPR:[0-9]+]]
// CHECK-DAG: dbg.declare({{.*}} %vla, metadata ![[VAR:[0-9]+]]
// CHECK-DAG: ![[VLAEXPR]] = !DILocalVariable(name: "__vla_expr", {{.*}} flags: DIFlagArtificial
// CHECK-DAG: ![[VLAEXPR]] = !DILocalVariable(name: "__vla_expr0", {{.*}} flags: DIFlagArtificial
// CHECK-DAG: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+2]]
// CHECK-DAG: !DISubrange(count: ![[VLAEXPR]])
int vla[s];
Expand Down
2 changes: 1 addition & 1 deletion test/CodeGenCXX/debug-info-vla.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ int (*fp)(int[][*]) = nullptr;
// CHECK: [[ELEM_TYPE]] = !{[[NOCOUNT:.*]]}
// CHECK: [[NOCOUNT]] = !DISubrange(count: -1)
//
// CHECK: [[VAR:![0-9]+]] = !DILocalVariable(name: "__vla_expr", {{.*}}flags: DIFlagArtificial
// CHECK: [[VAR:![0-9]+]] = !DILocalVariable(name: "__vla_expr0", {{.*}}flags: DIFlagArtificial
// CHECK: !DICompositeType(tag: DW_TAG_array_type,
// CHECK-NOT: size:
// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]]
Expand Down

0 comments on commit df5383b

Please sign in to comment.