This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Fix a crash when recursively callig a default member initializer.
ClosedPublic

Authored by cor3ntin on Jan 23 2023, 1:26 PM.

Details

Summary

This fixes a regression introduced by ca61961380, that would lead
to a segfault due to stack exhaustion when recursively calling
a default member initializer.

Fixes #60082

I'm not able to get clang to emit a stack exhaustion warning,
which it seems like it should be able to.

Diff Detail

Event Timeline

cor3ntin created this revision.Jan 23 2023, 1:26 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 23 2023, 1:26 PM
cor3ntin requested review of this revision.Jan 23 2023, 1:26 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 23 2023, 1:26 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

I could not find any tests that test for this warning.

clang/lib/Sema/SemaExpr.cpp
5930

I could not find any tests that test for this warning.

I'm unable to trigger the warning at all. I feel i should but just using that function resolves the crash, probably because it allocates more stack in a separate thread, and there is actually some code that avoids marking the same object used twice.
But the warning might still trigger on some platform, so i suspect the test i added might, sometimes, trigger a warning. I'm not exactly sure how to handle that

I could not find any tests that test for this warning.

I'm unable to trigger the warning at all. I feel i should but just using that function resolves the crash, probably because it allocates more stack in a separate thread, and there is actually some code that avoids marking the same object used twice.
But the warning might still trigger on some platform, so i suspect the test i added might, sometimes, trigger a warning. I'm not exactly sure how to handle that

Tests for stack space are always really challenging because triggering the failure is so system specific. We only have one test for it (test/SemaTemplate/stack-exhaustion.cpp)

But do we need to run these on separate threads in all of those places to address the issue?

"and there is actually some code that avoids marking the same object used twice." makes me wonder if we're missing an early return somewhere that would reduce stack usage more and avoid needing to spin up threads for this. (The upside to this change is that the code compiles more often but the downside is that we're not addressing the memory pressure issue, just kicking the can down the road a bit.)

I could not find any tests that test for this warning.

I'm unable to trigger the warning at all. I feel i should but just using that function resolves the crash, probably because it allocates more stack in a separate thread, and there is actually some code that avoids marking the same object used twice.
But the warning might still trigger on some platform, so i suspect the test i added might, sometimes, trigger a warning. I'm not exactly sure how to handle that

Tests for stack space are always really challenging because triggering the failure is so system specific. We only have one test for it (test/SemaTemplate/stack-exhaustion.cpp)

But do we need to run these on separate threads in all of those places to address the issue?

"and there is actually some code that avoids marking the same object used twice." makes me wonder if we're missing an early return somewhere that would reduce stack usage more and avoid needing to spin up threads for this. (The upside to this change is that the code compiles more often but the downside is that we're not addressing the memory pressure issue, just kicking the can down the road a bit.)

I agree for the most part, but the 'runWithSufficientStackSpace' doesn't run in a separate thread, it just wraps it in a function that makes our diagnostic for running out of memory better. But I think you're right, we probably should have SOMETHING that lets us exit early or defer constructing the initializers or something.

I could not find any tests that test for this warning.

I'm unable to trigger the warning at all. I feel i should but just using that function resolves the crash, probably because it allocates more stack in a separate thread, and there is actually some code that avoids marking the same object used twice.
But the warning might still trigger on some platform, so i suspect the test i added might, sometimes, trigger a warning. I'm not exactly sure how to handle that

Tests for stack space are always really challenging because triggering the failure is so system specific. We only have one test for it (test/SemaTemplate/stack-exhaustion.cpp)

But do we need to run these on separate threads in all of those places to address the issue?

"and there is actually some code that avoids marking the same object used twice." makes me wonder if we're missing an early return somewhere that would reduce stack usage more and avoid needing to spin up threads for this. (The upside to this change is that the code compiles more often but the downside is that we're not addressing the memory pressure issue, just kicking the can down the road a bit.)

I agree for the most part, but the 'runWithSufficientStackSpace' doesn't run in a separate thread, it just wraps it in a function that makes our diagnostic for running out of memory better. But I think you're right, we probably should have SOMETHING that lets us exit early or defer constructing the initializers or something.

That's not entirely accurate: https://github.com/llvm/llvm-project/blob/main/clang/include/clang/Basic/Stack.h#L40 which calls into https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/Stack.cpp#L66

It MIGHT get run in a new thread (if that's enabled) or it might not.

Aside from the commenting issue pointed out by @shafik, I think we should move the test case into its own test file in SemaCXX and that RUN line should *not* use -verify. This way, we can test that we don't crash but we don't have to worry about spurious test failures due to different machines having different stack exhaustion points.

cor3ntin updated this revision to Diff 516387.Apr 24 2023, 6:40 AM

Address comments, implement Aaron's clever solution, Rebase and add release note

cor3ntin updated this revision to Diff 516388.Apr 24 2023, 6:42 AM

Remove duplicated test

shafik accepted this revision.Apr 25 2023, 10:30 AM

LGTM

This revision is now accepted and ready to land.Apr 25 2023, 10:30 AM
cor3ntin updated this revision to Diff 518161.Apr 29 2023, 6:07 AM

I don't think this is actually testable, ultimately we may run out of stack
any way, the warning (when emitted) even say so.

I don't think this is actually testable, ultimately we may run out of stack
any way, the warning (when emitted) even say so.

Okay, that's a fair point and makes my suggestion invalid. I think you're right, testing this consistently will be tricky -- LGTM once the test is removed.

This revision was landed with ongoing or failed builds.May 1 2023, 2:21 PM
This revision was automatically updated to reflect the committed changes.