george.burgess.iv created this revision. george.burgess.iv added reviewers: LegalizeAdulthood, aaron.ballman. george.burgess.iv added a project: clang-tools-extra. Herald added subscribers: carlosgalvezp, xazax.hun. Herald added a project: All. george.burgess.iv requested review of this revision. Herald added a subscriber: cfe-commits.
Clang's `-Wvexing-parse` is enabled by default <https://godbolt.org/z/5Ec4f69sv>. When the vexing statement was _intended_ to be interpreted as a function that takes zero arguments, the function's declaration can be rewritten as `T foo(void);` to silence `-Wvexing-parse`. This workaround seems to upset `clang-tidy`. Given my own lack of understanding of the corners of C++ parsing, I'm... not entirely confident that this patch catches everything && has no unintended side-effects. The bits that `-Wvexing-parse` depends upon are stored within `DeclaratorChunk::FunctionTypeInfo`s, which seem to only exist during AST formation, so it's not clear to me how to directly get at that information from clang-tidy. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D126735 Files: clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp Index: clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp @@ -592,3 +592,9 @@ (void)a; } #undef return_t + +// Explicitly specifying `(void)` is a way to sidestep -Wvexing-parse, so we +// should not warn about it here. +void most_vexing_parse() { + int foo(void); +} Index: clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -109,9 +109,13 @@ } removeVoidArgumentTokens(Result, SourceRange(Start, End), "function definition"); - } else + } else if (!Function->getLexicalDeclContext()->isFunctionOrMethod()) { + // Only do this if our decl context is outside of a function or method; + // otherwise, the user may have explicitly written `(void)` to avoid Most + // Vexing Parse warnings. removeVoidArgumentTokens(Result, SourceRange(Start, End), "function declaration"); + } } bool isMacroIdentifier(const IdentifierTable &Idents, const Token &ProtoToken) {
Index: clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp =================================================================== --- clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp +++ clang-tools-extra/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp @@ -592,3 +592,9 @@ (void)a; } #undef return_t + +// Explicitly specifying `(void)` is a way to sidestep -Wvexing-parse, so we +// should not warn about it here. +void most_vexing_parse() { + int foo(void); +} Index: clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ clang-tools-extra/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -109,9 +109,13 @@ } removeVoidArgumentTokens(Result, SourceRange(Start, End), "function definition"); - } else + } else if (!Function->getLexicalDeclContext()->isFunctionOrMethod()) { + // Only do this if our decl context is outside of a function or method; + // otherwise, the user may have explicitly written `(void)` to avoid Most + // Vexing Parse warnings. removeVoidArgumentTokens(Result, SourceRange(Start, End), "function declaration"); + } } bool isMacroIdentifier(const IdentifierTable &Idents, const Token &ProtoToken) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits