diff options
| author | Haojian Wu <hokein@google.com> | 2017-02-28 15:29:52 +0000 |
|---|---|---|
| committer | Haojian Wu <hokein@google.com> | 2017-02-28 15:29:52 +0000 |
| commit | b780c59b9336c14c15aabc5546cb09df31e4f177 (patch) | |
| tree | 86a72cd91fdc5d871b0101f4e5e43acab8b7052b | |
| parent | 983c9b98e93691559647d5ba13c109b5f846ff45 (diff) | |
| download | bcm5719-llvm-b780c59b9336c14c15aabc5546cb09df31e4f177.tar.gz bcm5719-llvm-b780c59b9336c14c15aabc5546cb09df31e4f177.zip | |
[clang-tidy] Fix a false positive on modernize-use-nullptr check.
Summary:
The false positive happens on two neighbour CXXDefaultArgExpr AST nodes.
like below:
```
CXXFunctionalCastExpr 0x85c9670 <col:7, col:23> 'struct ZZ' functional cast to struct ZZ <ConstructorConversion>
`-CXXConstructExpr 0x85c9518 <col:7, col:23> 'struct ZZ' 'void (uint64, const uint64 *)'
|-CallExpr 0x85a0a90 <col:10, col:22> 'uint64':'unsigned long long'
| |-ImplicitCastExpr 0x85a0a78 <col:10> 'uint64 (*)(uint64)' <FunctionToPointerDecay>
| | `-DeclRefExpr 0x85a09f0 <col:10> 'uint64 (uint64)' lvalue Function 0x85a06a0 'Hash' 'uint64 (uint64)'
| `-CXXDefaultArgExpr 0x85a0ac8 <<invalid sloc>> 'uint64':'unsigned long long'
`-CXXDefaultArgExpr 0x85c94f8 <<invalid sloc>> 'const uint64 *'
```
For each particular CXXDefaultArgExpr node, we need to reset
FirstSubExpr, otherwise FirstSubExpr will refer to an incorrect expr.
Reviewers: alexfh
Reviewed By: alexfh
Subscribers: JDevlieghere, cfe-commits
Differential Revision: https://reviews.llvm.org/D30412
llvm-svn: 296479
| -rw-r--r-- | clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp | 4 | ||||
| -rw-r--r-- | clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp | 16 |
2 files changed, 19 insertions, 1 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp index 50c2f8906b4..967b6edd98f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.cpp @@ -190,8 +190,10 @@ public: bool VisitStmt(Stmt *S) { auto *C = dyn_cast<CastExpr>(S); // Catch the castExpr inside cxxDefaultArgExpr. - if (auto *E = dyn_cast<CXXDefaultArgExpr>(S)) + if (auto *E = dyn_cast<CXXDefaultArgExpr>(S)) { C = dyn_cast<CastExpr>(E->getExpr()); + FirstSubExpr = nullptr; + } if (!C) { FirstSubExpr = nullptr; return true; diff --git a/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp b/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp index e1ab843404e..42cdb2d5fe8 100644 --- a/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp +++ b/clang-tools-extra/test/clang-tidy/modernize-use-nullptr.cpp @@ -228,3 +228,19 @@ struct D { void test_default_argument() { D(nullptr); } + +// Test on two neighbour CXXDefaultArgExprs nodes. +typedef unsigned long long uint64; +struct ZZ { + explicit ZZ(uint64, const uint64* = NULL) {} +// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: use nullptr +// CHECK-FIXES: explicit ZZ(uint64, const uint64* = nullptr) {} + operator bool() { return true; } +}; + +uint64 Hash(uint64 seed = 0) { return 0; } + +void f() { + bool a; + a = ZZ(Hash()); +} |

