Skip to content

Commit 0ef5db3

Browse files
committed
Add an option "IgnoreStdFunctionArguments" to bugprone-argument-comment.
Standard library function has different prototypes between different compilers. For example, memset() in gcc, the prototype might be: void* memset(void* dest, int ch, size_t count); So if we run clang-tidy, it might add comment to the argument like this: memset(buffer, /*ch=*/0, count); But in vc, the prototype might be: void* memset(void* _Dst, int _Val, size_t _Size); So if we run clang-tidy, it might add comment to the argument like this: memset(buffer, /*_Val*/0, count); That means the same code might pass build under one compiler but fail under another compiler. This change tries to fix this issue. It adds an option "IgnoreStdFunctionArguments". If it is true, clang-tidy will try its best to recongize the standard function, and ignore the argument comment check on such function declared in system library.
1 parent a7533c8 commit 0ef5db3

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
2525
: ClangTidyCheck(Name, Context),
2626
StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0),
2727
IgnoreSingleArgument(Options.get("IgnoreSingleArgument", 0) != 0),
28+
IgnoreStdFunctionArguments(Options.get("IgnoreStdFunctionArguments", 0) != 0),
2829
CommentBoolLiterals(Options.get("CommentBoolLiterals", 0) != 0),
2930
CommentIntegerLiterals(Options.get("CommentIntegerLiterals", 0) != 0),
3031
CommentFloatLiterals(Options.get("CommentFloatLiterals", 0) != 0),
@@ -38,6 +39,7 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
3839
void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
3940
Options.store(Opts, "StrictMode", StrictMode);
4041
Options.store(Opts, "IgnoreSingleArgument", IgnoreSingleArgument);
42+
Options.store(Opts, "IgnoreStdFunctionArguments", IgnoreStdFunctionArguments);
4143
Options.store(Opts, "CommentBoolLiterals", CommentBoolLiterals);
4244
Options.store(Opts, "CommentIntegerLiterals", CommentIntegerLiterals);
4345
Options.store(Opts, "CommentFloatLiterals", CommentFloatLiterals);
@@ -254,6 +256,52 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
254256
if ((NumArgs == 0) || (IgnoreSingleArgument && NumArgs == 1))
255257
return;
256258

259+
if (IgnoreStdFunctionArguments) {
260+
const SourceManager& SourceMgr = Ctx->getSourceManager();
261+
const FileID FileId = SourceMgr.getFileID(Callee->getLocation());
262+
const unsigned int FileIdHash = FileId.getHashValue();
263+
if (StdFileIDs.find(FileIdHash) != StdFileIDs.end()) {
264+
// The function is declared in a standard library header file.
265+
// Ignore the argument comment check.
266+
return;
267+
}
268+
269+
if (NotStdFileIDs.find(FileIdHash) == NotStdFileIDs.end()) {
270+
// Currently, we don't know whether this function is declared
271+
// in a standard library header file or not. Let's make the
272+
// following assumption: if the header file of this function
273+
// exists under the same folder (or sub folder) of <string>
274+
// or <stdio.h>, we assume this function is declared in a
275+
// header file of standard library.
276+
const FileEntry* FileEntry = SourceMgr.getFileEntryForID(FileId);
277+
if (FileEntry) {
278+
llvm::StringRef Path = FileEntry->tryGetRealPathName();
279+
while (llvm::sys::path::has_parent_path(Path)) {
280+
Path = llvm::sys::path::parent_path(Path);
281+
SmallString<256> StdStringFilePath = Path, StdioFilePath = Path;
282+
llvm::sys::path::append(StdStringFilePath, "string");
283+
llvm::sys::path::append(StdioFilePath, "stdio.h");
284+
if (llvm::sys::fs::exists(StdStringFilePath) ||
285+
llvm::sys::fs::exists(StdioFilePath)) {
286+
// Find <string> or <stdio.h> in the same folder or
287+
// one of the parent folder. Assume the function is
288+
// declared in a standard library header file also.
289+
// Save the file id hash for next check and ignore
290+
// the argument comment check.
291+
StdFileIDs.insert(FileIdHash);
292+
return;
293+
}
294+
}
295+
}
296+
// Can't find <string> or <stdio.h> in the same folder or
297+
// all of the parent folders. Assume the function is not
298+
// declared in a header file of standard library. Save the
299+
// file id hash for next check and continue the argument
300+
// comment check.
301+
NotStdFileIDs.insert(FileIdHash);
302+
}
303+
}
304+
257305
auto MakeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) {
258306
return Lexer::makeFileCharRange(CharSourceRange::getCharRange(Begin, End),
259307
Ctx->getSourceManager(),

clang-tools-extra/clang-tidy/bugprone/ArgumentCommentCheck.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "../ClangTidyCheck.h"
1313
#include "llvm/Support/Regex.h"
14+
#include <unordered_set>
1415

1516
namespace clang {
1617
namespace tidy {
@@ -42,6 +43,7 @@ class ArgumentCommentCheck : public ClangTidyCheck {
4243
private:
4344
const unsigned StrictMode : 1;
4445
const unsigned IgnoreSingleArgument : 1;
46+
const unsigned IgnoreStdFunctionArguments : 1;
4547
const unsigned CommentBoolLiterals : 1;
4648
const unsigned CommentIntegerLiterals : 1;
4749
const unsigned CommentFloatLiterals : 1;
@@ -50,6 +52,8 @@ class ArgumentCommentCheck : public ClangTidyCheck {
5052
const unsigned CommentCharacterLiterals : 1;
5153
const unsigned CommentNullPtrs : 1;
5254
llvm::Regex IdentRE;
55+
std::unordered_set<unsigned> StdFileIDs;
56+
std::unordered_set<unsigned> NotStdFileIDs;
5357

5458
void checkCallArgs(ASTContext *Ctx, const FunctionDecl *Callee,
5559
SourceLocation ArgBeginLoc,

clang-tools-extra/docs/clang-tidy/checks/bugprone-argument-comment.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Options
3232

3333
When true, the check will ignore the single argument.
3434

35+
.. option:: IgnoreStdFunctionArguments
36+
37+
When true, the check will ignore functions declared in standard libraries.
38+
3539
.. option:: CommentBoolLiterals
3640

3741
When true, the check will add argument comments in the format
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \
2+
// RUN: -config="{CheckOptions: [ \
3+
// RUN: {key: bugprone-argument-comment.IgnoreStdFunctionArguments, value: 1}, \
4+
// RUN: {key: bugprone-argument-comment.CommentIntegerLiterals, value: 1}]}" --
5+
6+
#include <string.h>
7+
8+
void g(int i);
9+
10+
void foo()
11+
{
12+
g(1);
13+
// CHECK-MESSAGES: [[@LINE-1]]:7: warning: argument comment missing for literal argument 'i' [bugprone-argument-comment]
14+
// CHECK-FIXES: g(/*i=*/1);
15+
16+
char buffer[1024];
17+
memset(buffer, 0, sizeof(buffer));
18+
}

0 commit comments

Comments
 (0)