In gcc-11, -Wnonnull considers the implicit this argument of every C++ nonstatic member function to have been implicitly declared with attribute nonnull and triggers warnings for calls where the pointer is null. [1]
Should clang also do this? This change helped webkit identify and fix some issues. [2][3][4][5]
Building clang trunk with gcc-11 produces 13 new warnings related to this enhancement. They are in MachineModuleInfo.cpp and RangeAdapterTest.cpp.[6] Do these look like valid issues?
-Luke
[1] https://gcc.gnu.org/gcc-11/changes.html\
[2] https://bugs.webkit.org/show_bug.cgi?id=224838
[3] https://bugs.webkit.org/show_bug.cgi?id=224826
[4] https://trac.webkit.org/changeset/276343/webkit
[5] https://bugs.webkit.org/show_bug.cgi?id=224452
[6] https://pastebin.com/EJTZphGm
Sure, those things seem legit - I think we have some sanitizer mode (& some optimizations, when the sanitizer checks aren’t enabled) for checking non-null-ness in various cases, which probably would hit these cases (though given that I think various sanitizer self host builds are checked regularly, I wonder if there’s an interesting explanation for why the cases in [6] were not found already by runtime analysis like that) - probably makes sense to catch them at compile time where we can. Though clang’s warnings aren’t interprocedural like it looks like some of these warnings in [6] are, so clang might still not catch all of them.
The first warning looks valid, although it doesn’t happen at runtime.
-
In constructor ‘llvm::MachineModuleInfo::MachineModuleInfo(const llvm::LLVMTargetMachine*)’,
-
inlined from ‘llvm::MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(const llvm::LLVMTargetMachine*)’ at /llvm/lib/CodeGen/MachineModuleInfo.cpp:357:26,
-
inlined from ‘llvm::Pass* llvm::callDefaultCtor() [with PassName = llvm::MachineModuleInfoWrapperPass]’ at /llvm/include/llvm/PassSupport.h:80:76:
-
/llvm/lib/CodeGen/MachineModuleInfo.cpp:240:51: warning: ‘this’ pointer is null [-Wnonnull]
-
240 | Context.setObjectFileInfo(TM->getObjFileLowering());
-
I believe it should be a simple matter of deleting the zero-arg constructor. I’ll try that and push it.
I note that the GCC warning points to an odd place, though – it probably should be pointing to the construction TM(*TM), which initializes a reference with null, which is already UB.
MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
: TM(*TM), …
However, the rest of the warnings come from:
decltype(static_cast<const TypeParam *>(nullptr)->rbegin())>::value
which I think is a false-positive in GCC’s warning.
TTBOMK, calling a method on nullptr in an unevaluated context (e.g. decltype, non-vla-sizeof, etc) is not UB, and therefore should not emit a warning.
The first warning looks valid, although it doesn’t happen at runtime.
-
In constructor ‘llvm::MachineModuleInfo::MachineModuleInfo(const llvm::LLVMTargetMachine*)’,
-
inlined from ‘llvm::MachineModuleInfoWrapperPass::MachineModuleInfoWrapperPass(const llvm::LLVMTargetMachine*)’ at /llvm/lib/CodeGen/MachineModuleInfo.cpp:357:26,
-
inlined from ‘llvm::Pass* llvm::callDefaultCtor() [with PassName = llvm::MachineModuleInfoWrapperPass]’ at /llvm/include/llvm/PassSupport.h:80:76:
-
/llvm/lib/CodeGen/MachineModuleInfo.cpp:240:51: warning: ‘this’ pointer is null [-Wnonnull]
-
240 | Context.setObjectFileInfo(TM->getObjFileLowering());
-
I believe it should be a simple matter of deleting the zero-arg constructor. I’ll try that and push it.
I note that the GCC warning points to an odd place, though – it probably should be pointing to the construction TM(*TM), which initializes a reference with null, which is already UB.
MachineModuleInfo::MachineModuleInfo(const LLVMTargetMachine *TM)
: TM(*TM), …
However, the rest of the warnings come from:
decltype(static_cast<const TypeParam *>(nullptr)->rbegin())>::value
which I think is a false-positive in GCC’s warning.
Oh, yeah, if it’s in an unevaluated context - agreed, that’s a false positive. (though we could probably also just make that code nicer to read by using std::declval<const TypeParam&>().rbegin(), I think?