clang-tidy: hard to repro bug in the 'modernize-use-default-member-init' check

Folks, I’m trying understand a clang-tidy bug where the ‘modernize-use-default-member-init’ check misbehaves on this (reduced) input:

struct Thing {
Thing(int arg) : a(arg), b(0) {}
int a, b;

The check works correctly when running clang-tidy without a compilation DB. The tool complains, but works correctly. Things also work correctly in the LIT tests…

Yet when running with a compilation DB, I get this output after fixes are applied (notice the trailing comma, which makes the code ill-formed):

struct Thing {
Thing(int arg) : a(arg), {}
int a, b{0};

How do I write a unit test for this? I mean how do I create a reliable repro?


I’d probably start by analyzing the bug, maybe figuring out the root cause - then work backwards for the test case to commit along with the test. (figuring out the root cause might reveal easier ways to reproduce the bug, once it’s understood)

To root cause the bug, I’d try parallel debugging sessions - with and without a compilation DB, for instance - stepping through each, and seeing where the behavior diverges, and why it diverges.

Well, I’ve just exported the fix with --export-fixes and the core data is identical in both invocations:


  • DiagnosticName: modernize-use-default-member-init
    Message: ‘use default member initializer for ‘‘b’’’
    FilePath: ‘fixed.cpp’
    FileOffset: 63
  • FilePath: ‘fixed.cpp’
    Offset: 44
    Length: 5
    ReplacementText: ‘’
  • FilePath: ‘fixed.cpp’
    Offset: 64
    Length: 0
    ReplacementText: ‘{0}’

Yet the fix is, apparently, applied in a different way… Hmm… I’ve never looked at how/where these insertions/deletions are applied. I’ll have to do some RTFM…