diff options
author | Bolshakov <bolsh.andrey@yandex.ru> | 2022-06-26 23:54:52 +0300 |
---|---|---|
committer | Kim Gräsman <kim.grasman@gmail.com> | 2022-07-16 18:30:23 +0200 |
commit | b46a96e5a646fc684c8eed95eb63f4e6edc9d679 (patch) | |
tree | 105f635ca667a6f7e46221038ef724ba0abc36b2 | |
parent | bab51b55ab092cb74ea62f14042cf66232ccfb40 (diff) |
Fix autocast to reference
CastExpr for constructor conversion is absent in the AST in such a case
-rw-r--r-- | iwyu.cc | 33 | ||||
-rw-r--r-- | tests/cxx/iwyu_stricter_than_cpp-d2.h | 4 |
2 files changed, 22 insertions, 15 deletions
@@ -2002,19 +2002,9 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> { // Need the full to-type so we can call its constructor. case clang::CK_ConstructorConversion: - // 'Autocast' -- calling a one-arg, non-explicit constructor - // -- is a special case when it's done for a function call. - // iwyu requires the function-writer to provide the #include - // for the casted-to type, just so we don't have to require it - // here. *However*, the function-author can override this - // iwyu requirement, in which case we're responsible for the - // casted-to type. See IwyuBaseASTVisitor::VisitFunctionDecl. - if (!current_ast_node()->template HasAncestorOfType<CallExpr>() || - ContainsKey( - GetCallerResponsibleTypesForAutocast(current_ast_node()), - RemovePointersAndReferences(to_type))) { + // 'Autocast' in function calls is handled in VisitCXXConstructExpr. + if (!current_ast_node()->template HasAncestorOfType<CallExpr>()) required_full_types.push_back(to_type); - } break; // Need the full from-type so we can call its 'operator <totype>()'. case clang::CK_UserDefinedConversion: @@ -2286,6 +2276,25 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> { if (CanIgnoreCurrentASTNode()) return true; ReportIfReferenceVararg(expr->getArgs(), expr->getNumArgs(), expr->getConstructor()); + + // 'Autocast' -- calling a one-arg, non-explicit constructor + // -- is a special case when it's done for a function call. + // iwyu requires the function-writer to provide the #include + // for the casted-to type, just so we don't have to require it + // here. *However*, the function-author can override this + // iwyu requirement, in which case we're responsible for the + // casted-to type. See IwyuBaseASTVisitor::VisitFunctionDecl. + // Explicitly written CXXTemporaryObjectExpr are ignored here. + if (expr->getStmtClass() == Stmt::StmtClass::CXXConstructExprClass) { + const Type* type = expr->getType().getTypePtr(); + if (current_ast_node()->template HasAncestorOfType<CallExpr>() && + ContainsKey(GetCallerResponsibleTypesForAutocast(current_ast_node()), + RemoveReferenceAsWritten(type))) { + if (!CanIgnoreType(type)) + ReportTypeUse(CurrentLoc(), type); + } + } + return true; } diff --git a/tests/cxx/iwyu_stricter_than_cpp-d2.h b/tests/cxx/iwyu_stricter_than_cpp-d2.h index f1b101a..4089d95 100644 --- a/tests/cxx/iwyu_stricter_than_cpp-d2.h +++ b/tests/cxx/iwyu_stricter_than_cpp-d2.h @@ -21,9 +21,7 @@ void CallTwiceDeclaredFunction() { // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h TwiceDeclaredFunction(1); - // This *should* be exactly the same, but doesn't seem to be: - // clang leaves out the constructor-conversion AST node. - // TODO(csilvers): IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h + // IWYU: IndirectStruct2 is...*iwyu_stricter_than_cpp-i2.h TwiceDeclaredRefFunction(1); } |