This is an archive of the discontinued LLVM Phabricator instance.

[debug-info][codegen] Prevent creation of self-referential SP node
ClosedPublic

Authored by fdeazeve on Feb 13 2023, 8:30 AM.

Details

Summary

The function CGDebugInfo::EmitFunctionDecl is supposed to create a
declaration -- never a _definition_ -- of a subprogram. This is made
evident by the fact that the SPFlags never have the "Declaration" bit
set by that function.

However, when EmitFunctionDecl calls DIBuilder::createFunction, it
still tries to fill the "Declaration" argument by passing it the result
of getFunctionDeclaration(D). This will query an internal cache of
previously created declarations and, for most code paths, we return
nullptr; all is good.

However, as reported in [0], there are pathological cases in which we
attempt to recreate a declaration, so the cache query succeeds,
resulting in a subprogram declaration whose declaration field points to
another declaration. Through a series of RAUWs, the declaration field
ends up pointing to the SP itself. Self-referential MDNodes can't be
unique, which causes the verifier to fail (declarations must be
unique).

We can argue that the caller should check the cache first, but this is
not a correctness issue (declarations are unique anyway). The bug is
that CGDebugInfo::EmitFunctionDecl should always pass nullptr to the
declaration argument of DIBuilder::createFunction, expressing the fact
that declarations don't point to other declarations. AFAICT this is not
something for which any reasonable meaning exists.

This seems a lot like a copy-paste mistake that has survived for ~10
years, since other places in this file have the exact same call almost
token-by-token.

I've tested this by compiling LLVMSupport with and without the patch, O2
and O0, and comparing the dwarfdump of the lib. The dumps are identical
modulo the attributes decl_file/producer/comp_dir.

[0]: https://github.com/llvm/llvm-project/issues/59241

Diff Detail

Unit TestsFailed

Event Timeline

fdeazeve created this revision.Feb 13 2023, 8:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 13 2023, 8:30 AM
fdeazeve requested review of this revision.Feb 13 2023, 8:30 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald Transcript

Any testing suggestions here? I can use what we have on GH (cpp -> codegen test), but I'm not sure if there's a finer grained test we could use.

aprantl accepted this revision.Feb 13 2023, 1:03 PM
aprantl added inline comments.
llvm/lib/IR/Verifier.cpp
1404

Can you a new test for this?

This revision is now accepted and ready to land.Feb 13 2023, 1:03 PM

Any testing suggestions here? I can use what we have on GH (cpp -> codegen test), but I'm not sure if there's a finer grained test we could use.

I was thinking of a very small IR test similar to llvm/test/Verifier/disubprogram-name-match-only.ll.

fdeazeve updated this revision to Diff 497321.Feb 14 2023, 7:20 AM

Added verifier test

Any testing suggestions here? I can use what we have on GH (cpp -> codegen test), but I'm not sure if there's a finer grained test we could use.

I was thinking of a very small IR test similar to llvm/test/Verifier/disubprogram-name-match-only.ll.

Yup, good idea, this should be enough! Added.

aprantl accepted this revision.Feb 14 2023, 8:51 AM

Test looks good!

fdeazeve updated this revision to Diff 497713.Feb 15 2023, 9:47 AM

Fixed clang format issue

This revision was landed with ongoing or failed builds.Feb 20 2023, 11:23 AM
This revision was automatically updated to reflect the committed changes.