Page MenuHomePhabricator

Fix PR28181: Prevent operator overloading related assertion failure crash that happens in C only
ClosedPublic

Authored by arphaman on Oct 3 2016, 3:05 PM.

Details

Summary

This patch fixes a crash that happens because of an assertion failure in C mode only. The assertion failure happens because of a cast to a C++ record decl in code that assumes (correctly, AFAIK) that overloaded operator handling is used in C++ mode only.

This patch approaches this problem in the following manner: when clang isn't in C++ mode, it exits early from the method 'Sema::CreateOverloadedBinOp'. The operator handling is performed using the 'Sema::CreateBuiltinBinOp' method when exiting the previously mentioned method. I think that this approach works because, AFAIK, clang doesn't support operator overloading without LangOpts.CPlusPlus, so it doesn't need to handle the overloading in the same way, and redirecting to builtin operator handling deals with the C operators correctly. I also tried other approaches and strategies but they didn't seem to work as well as this one.

I'm not familiar with all the intricacies of Sema, and I realize that this might be the wrong approach for this problem. Please let me know if this a sound strategy or not.

This bug is a regression since r236337.

Diff Detail

Repository
rL LLVM

Event Timeline

arphaman updated this revision to Diff 73343.Oct 3 2016, 3:05 PM
arphaman retitled this revision from to Fix PR28181: Prevent operator overloading related assertion failure crash that happens in C only.
arphaman updated this object.
arphaman added reviewers: rsmith, rjmccall.
arphaman set the repository for this revision to rL LLVM.
arphaman added a subscriber: cfe-commits.
rsmith added inline comments.Oct 3 2016, 3:29 PM
lib/Sema/SemaOverload.cpp
11750 ↗(On Diff #73343)

We should never be calling this function outside of C++ mode.

It looks like the bug is in Sema::BuildBinOp -- in C, it should call CorrectDelayedTyposInExpr before doing almost anything else. The relevant code is currently in CreateBuiltinBinOp, which is too late. Moving that code to the start of BuildBinOp should solve the problem.

arphaman updated this revision to Diff 73460.Oct 4 2016, 5:34 AM
arphaman marked an inline comment as done.

Thanks for the response,

I updated the patch with a approach that you suggested - now Sema::CreateOverloadedBinOp isn't called in C mode (I have an assertion for this in Sema::CreateOverloadedBinOp, but I'll commit it separately after).

I also tried moving the CorrectDelayedTyposInExpr code from Sema::CreateBuiltinBinOp to Sema::BuildBinOp as you suggested, but it didn't seem to have any effect whatsoever - it didn't seem to change the behavior of anything with respect to this bug or llvm's test suite. Therefore, I decided to leave it in its original location in this diff. Perhaps I've misunderstood your suggestion?

bruno accepted this revision.Jan 18 2017, 11:42 AM
bruno added a subscriber: bruno.

LGTM!

lib/Sema/SemaExpr.cpp
11523 ↗(On Diff #83822)

Looks like you can fold both conditions below into one and check getLangOpts().CPlusPlus only once

This revision is now accepted and ready to land.Jan 18 2017, 11:42 AM
This revision was automatically updated to reflect the committed changes.
arphaman marked an inline comment as done.