This is an archive of the discontinued LLVM Phabricator instance.

[analyzer] pr34766: Fix a crash on explicit construction of std::initializer_list.
ClosedPublic

Authored by NoQ on Nov 8 2017, 8:03 AM.

Details

Summary

std::initializer_list objects can be constructed sort of explicitly, eg. (std::initializer_list<int>){12}. This produces an AST that looks like

CompoundLiteralExpr 0x11987f1a0 'std::initializer_list<int>':'class std::initializer_list<int>'
`-CXXStdInitializerListExpr 0x11987f188 'std::initializer_list<int>':'class std::initializer_list<int>'
  `-MaterializeTemporaryExpr 0x11987f170 'const int [1]' xvalue
    `-InitListExpr 0x11987f128 'const int [1]'
      `-IntegerLiteral 0x11987cd18 'int' 12

We crash because we did not expect to see CompoundLiteralExpr containing CXXStdInitializerListExpr.

It seems correct to pass the value through CompoundLiteralExpr transparently (the value is currently a conjured structure-symbol of initializer_list type, which sounds like a correct value for the expression, even if not super verbose), hence the patch.

Diff Detail

Repository
rL LLVM

Event Timeline

NoQ created this revision.Nov 8 2017, 8:03 AM

I think I lack context to completely get what is going on here: I assume we don't model the assignment here?

lib/StaticAnalyzer/Core/ExprEngineC.cpp
533 ↗(On Diff #122094)

Empty "if" looks weird, why not just negate the condition, and then you could get rid of "else"?

NoQ added a comment.Nov 8 2017, 11:39 PM

I think I lack context to completely get what is going on here: I assume we don't model the assignment here?

  • We model IntegralLiteral as nonloc::ConcreteInt 12 S32b.
  • We model InitListExpr as nonloc::CompoundVal { 12 S32b }.
  • We model MaterializeTemporaryExpr as loc::MemRegionVal &temp_object{const int [1], {12}} in which {12 S32b} is stored, retroactively creating the location in which the list was supposed to be present from the start (TODO: why not CompoundLiteralRegion?).
  • We do not model CXXStdInitializerListExpr or internals of std::initializer_list, hence the value of this expresssion, conservatively, is conj_$0{std::initializer_list<int>}. See also D35216.
  • We now model CompoundLiteralExpr as conj_$0{std::initializer_list<int>} as no-op.
This revision is now accepted and ready to land.Nov 10 2017, 11:11 AM

Is anything holding this patch?

This revision was automatically updated to reflect the committed changes.