This is an archive of the discontinued LLVM Phabricator instance.

Fix crash when evaluating constant expressions involving nullptr
ClosedPublic

Authored by t.p.northover on May 25 2017, 2:44 PM.

Details

Reviewers
rsmith
Summary

For the simple casts in the test, we were crashing because the ZeroInitialization function created an LValue with an unexpected SubobjectDesignator: it was valid but didn't actually refer to a valid MostDerivedType.

Since PointerExprEvaluator actually creates an LValue based notionally on what you'd get if you dereferenced the pointer (I think), the MostDerivedType should be set by stripping the pointer from the type as in this patch.

The theoretically simpler solution of providing an invalid SubobjectDesignator (as happens for an int to pointer cast) is incorrect because nullptr has more possible uses in constexprs than other casts of integers.

Does my reasoning look sound? I've been all over that file before I finally thought I knew what was going on and I'm still not entirely confident.

Diff Detail

Event Timeline

t.p.northover created this revision.May 25 2017, 2:44 PM
rsmith added a subscriber: rsmith.May 25 2017, 2:55 PM
rsmith added inline comments.
clang/lib/AST/ExprConstant.cpp
5505–5507

This is the only caller of set() that passes more than three arguments (that is, the only caller that passes true as IsNullPtr_). It seems that such calls would always be unsafe / wrong, so I think we can do better than this.

How about this: split set() into two functions: for one of them, remove the last two parameters (IsNullPtr_ and Offset_), and for the other one, rename to setNull() and just pass a QualType and offset.

Sounds very reasonable to me. I've uploaded a new diff.

rsmith accepted this revision.May 25 2017, 4:15 PM

Thanks!

This revision is now accepted and ready to land.May 25 2017, 4:15 PM
t.p.northover closed this revision.May 25 2017, 7:16 PM

Thanks Richard. I've committed this as r303957.