Index: clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ clang-tools-extra/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -26,12 +26,14 @@ compoundStmt(forEach( ifStmt(unless(isConstexpr()), // FIXME: Explore alternatives for the - // `if (T x = ...) {... return; } else { }` - // pattern: + // `if (T x = ...) {... return; } else { }` and + // 'if (T x = ...; cond) {... return; } else { use }' + // patterns: // * warn, but don't fix; // * fix by pulling out the variable declaration out of // the condition. unless(hasConditionVariableStatement(anything())), + unless(hasInitStorage()), hasThen(stmt(anyOf(InterruptsControlFlow, compoundStmt(has(InterruptsControlFlow))))), hasElse(stmt().bind("else"))) Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -4297,6 +4297,22 @@ return Node.isConstexpr(); } +/// Matches selection statements with initializer +/// +/// Given: +/// \code +/// if (int foo = bar(); bar > 0) {} +/// switch (int baz = bar(); baz - 1) {} +/// \endcode +/// IfStmt(hasInitStorage()) +/// matches the declaration of foo. +/// SwitchStmt(hasInitStorage()) +/// matches the declaration of baz. +AST_POLYMORPHIC_MATCHER(hasInitStorage, + AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, SwitchStmt)) { + return Node.hasInitStorage(); +} + /// Matches the condition expression of an if statement, for loop, /// switch statement or conditional operator. ///