Fix -use-nullptr problems with assert()

If a cast expression (NullToPointer) is detected in a function-like macro
parameter, we should use the spelling location instead of the expansion
location. Using SourceManager::getFileLoc() fixes this problem.

Also added testcases for this bug.

Fixes: PR15279
Author: Tareq A Siraj <tareq.a.siraj@intel.com>
Reviewer: klimek
llvm-svn: 175399
This commit is contained in:
Edwin Vane 2013-02-17 16:45:54 +00:00
parent 1cba0a8e0a
commit 4ad00b46fb
2 changed files with 33 additions and 4 deletions

View File

@ -57,6 +57,10 @@ public:
SourceLocation StartLoc = FirstCast->getLocStart();
SourceLocation EndLoc = FirstCast->getLocEnd();
// If the start/end location is a macro, get the expansion location.
StartLoc = SM.getFileLoc(StartLoc);
EndLoc = SM.getFileLoc(EndLoc);
if (SM.getFileID(StartLoc) == SM.getFileID(EndLoc) &&
SM.isFromMainFile(StartLoc) && SM.isFromMainFile(EndLoc)) {
CharSourceRange Range(SourceRange(StartLoc, EndLoc), true);
@ -100,10 +104,9 @@ void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) {
if (SM.getFileID(StartLoc) != SM.getFileID(EndLoc))
return;
if (StartLoc.isMacroID())
StartLoc = SM.getExpansionLoc(StartLoc);
if (EndLoc.isMacroID())
EndLoc = SM.getExpansionLoc(EndLoc);
// If the start/end location is a macro, get the expansion location.
StartLoc = SM.getFileLoc(StartLoc);
EndLoc = SM.getFileLoc(EndLoc);
if (!SM.isFromMainFile(StartLoc) || !SM.isFromMainFile(EndLoc))
return;

View File

@ -178,3 +178,29 @@ int test_function_return6() {
return g_null;
// CHECK: return g_null;
}
// Test function-like macros where the parameter to the macro (expression)
// results in a nullptr.
void __dummy_assert_fail() {}
void test_function_like_macro1() {
// This tests that the CastSequenceVisitor is working properly.
#define my_assert(expr) \
((expr) ? static_cast<void>(expr) : __dummy_assert_fail())
int *p;
my_assert(p != 0);
// CHECK: my_assert(p != nullptr);
#undef my_assert
}
void test_function_like_macro2() {
// This tests that the implicit cast is working properly.
#define my_macro(expr) \
(expr)
int *p;
my_macro(p != 0);
// CHECK: my_macro(p != nullptr);
#undef my_macro
}