This is an archive of the discontinued LLVM Phabricator instance.

Fix a crash when emitting DIEs for variable-length arrays
ClosedPublic

Authored by aprantl on Feb 5 2018, 5:23 PM.

Details

Summary

VLAs may refer to a previous DIE to express the DW_AT_count of their type. Clang generates an artificial "vla_expr" variable for this. If this DIE hasn't been created yet LLVM asserts. This patch fixes this by sorting the local variables so that dependencies come before they are needed. It also replaces the linear scan in DWARFFile with a std::map, which can be faster.

Diff Detail

Repository
rL LLVM

Event Timeline

aprantl created this revision.Feb 5 2018, 5:23 PM
aprantl updated this revision to Diff 132923.Feb 5 2018, 5:26 PM
davide added a subscriber: davide.Feb 5 2018, 5:29 PM
davide added inline comments.
lib/CodeGen/AsmPrinter/DwarfFile.h
52 ↗(On Diff #132923)

Do you really need std::map<> here? Can't you use an LLVM container?

aprantl added inline comments.Feb 6 2018, 10:10 AM
lib/CodeGen/AsmPrinter/DwarfFile.h
52 ↗(On Diff #132923)

Is there a better container for this? I need something that allows me to

  1. check whether an element already exists while building the list
  2. traverse all elements in order at the end.

DenseMap doesn't support (2), so the only other alternative I could come up with was a SmallVector or a std::list that is kept sorted after each insert by using std::lower_bound to look up the insertion point. Using a std::list instead the SmallVector would be more memory efficient than the std::map. Using a SmallVector would use least memory, but has quadratic worst-case behavior. Any preferences/suggestions?

Some comments inline, but this is almost good to go IMHO.

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
573–583 ↗(On Diff #132923)

I think the logic here is correct, but I don't necessarily like all this level of nesting.
Can you try to use something like llvm::any_of or reduce indentations with early exits?
i.e.

DICompositeType *Array = dyn_cast<>();
if (!Array)
  return false
[...]
586 ↗(On Diff #132923)

that variables that variables :)

lib/CodeGen/AsmPrinter/DwarfFile.h
52 ↗(On Diff #132923)

I think a map is fine, but I'd add a comment here explaining the rationale, if you don't mind.

Andi added a subscriber: Andi.Feb 6 2018, 10:42 AM
aprantl updated this revision to Diff 133070.Feb 6 2018, 1:41 PM

Address review feedback from Davide.

davide accepted this revision.Feb 6 2018, 1:45 PM

LGTM. One minor comment inline. Feel free to decide whether you want to address & commit (no need for another round trip)

lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
576 ↗(On Diff #133070)

Terrific, looks much better now :)

604 ↗(On Diff #133070)

sortLocalVars can be an inline lambda, but hey, up to you.

This revision is now accepted and ready to land.Feb 6 2018, 1:45 PM
aprantl updated this revision to Diff 133081.Feb 6 2018, 2:17 PM

smaller testcase (thanks Volodymyr!)

This revision was automatically updated to reflect the committed changes.
vsapsai added a subscriber: vsapsai.Feb 6 2018, 4:18 PM
vsapsai added inline comments.
llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
590

std::stable_sort requires comparison function object to satisfy Compare concept. It is mentioned that comp(a, b) establishes strict weak ordering relation. One of the requirements of this ordering is transitivity of incomparability, i.e. if x <> y and y <> z then it should be x <> z. But with dependency relation it is possible that x and y are independent, y and z are independent, but x depends on z.

During my testing I had DbgVariable in the following order

array
count
vla_expr

and the sorting proceeded as

is [1] < [0] => false, no swapping
is [2] < [1] => false, no swapping
finish sort

We didn't even check that array depends on vla_expr.

Looks like for dependency relation something like stable topological sorting is more appropriate.

aprantl reopened this revision.Feb 7 2018, 11:36 AM
This revision is now accepted and ready to land.Feb 7 2018, 11:36 AM
aprantl closed this revision.Feb 7 2018, 11:37 AM