diff options
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/blockblock.cxx | 25 | ||||
-rw-r--r-- | compilerplugins/clang/test/blockblock.cxx | 16 |
2 files changed, 41 insertions, 0 deletions
diff --git a/compilerplugins/clang/blockblock.cxx b/compilerplugins/clang/blockblock.cxx index 8405609af3df..f1d9ec7a9d61 100644 --- a/compilerplugins/clang/blockblock.cxx +++ b/compilerplugins/clang/blockblock.cxx @@ -43,6 +43,7 @@ public: } bool VisitCompoundStmt(CompoundStmt const * ); + bool VisitCaseStmt(CaseStmt const * ); }; bool BlockBlock::VisitCompoundStmt(CompoundStmt const * compound) @@ -74,6 +75,30 @@ bool BlockBlock::VisitCompoundStmt(CompoundStmt const * compound) return true; } +bool BlockBlock::VisitCaseStmt(CaseStmt const * caseStmt) +{ + if (ignoreLocation(caseStmt)) + return true; + auto compoundStmt = dyn_cast<CompoundStmt>(caseStmt->getSubStmt()); + if (!compoundStmt) + return true; + if (compoundStmt->size() != 2) + return true; + auto it = compoundStmt->body_begin(); + auto inner1 = *it; + if (!isa<CompoundStmt>(inner1)) + return true; + ++it; + if (!isa<BreakStmt>(*it)) + return true; + report( + DiagnosticsEngine::Warning, + "block directly inside block", + compat::getBeginLoc(compoundStmt)) + << compoundStmt->getSourceRange(); + return true; +} + loplugin::Plugin::Registration< BlockBlock > blockblock("blockblock", true); } diff --git a/compilerplugins/clang/test/blockblock.cxx b/compilerplugins/clang/test/blockblock.cxx index bd48ed7d38fa..422430f9c1cd 100644 --- a/compilerplugins/clang/test/blockblock.cxx +++ b/compilerplugins/clang/test/blockblock.cxx @@ -21,6 +21,22 @@ int f(bool b1, bool b2) { return 1; } +void foo(int x) +{ + switch (x) + { + case 1: break; + case 2: {} break; + case 3: + { // expected-error {{block directly inside block [loplugin:blockblock]}} + { + } + break; + } + } +} + + int main() { // expected-error {{block directly inside block [loplugin:blockblock]}} { // expected-note {{inner block here [loplugin:blockblock]}} int x = 1; |