diff options
author | Volodymyr Sapsai <vsapsai@users.noreply.github.com> | 2017-07-03 14:36:21 -0700 |
---|---|---|
committer | Kim Grasman <kim.grasman@gmail.com> | 2017-07-16 11:26:23 +0200 |
commit | 6a7b17546b630fe8587d2af37e8446199adfa26b (patch) | |
tree | 4532c750d19bb011813193d9750dc04a5e009eec | |
parent | 79083f40153b3e21425d988bde031f1a206c3c5a (diff) |
Fix requiring allocator for getting container iterator with libc++. (#448)
libc++ code is
template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::begin() _NOEXCEPT
{
return __make_iter(this->__begin_);
}
and we reported use of allocator when visiting `vector<_Tp, _Allocator>`
because here `_Allocator` is not a default template argument. There was
no such problem in libstdc++ because there `begin` is defined inside a class.
Also I wasn't able to reproduce the issue with non-STL types because for
not precomputed types we replayed template arguments usage. And when we
populate the cache we see which template arguments are default so there
are no problems during replay.
Update test to remove method calls using object template arguments. As result,
on macOS it fixed errors
tests/cxx/badinc.cc:1534: Unexpected diagnostic:
I2_Enum is defined in "tests/cxx/badinc-i2.h", which isn't directly #included.
tests/cxx/badinc.cc:1580: Unexpected diagnostic:
I2_Enum is defined in "tests/cxx/badinc-i2.h", which isn't directly #included.
but introduced another error
tests/cxx/badinc.cc:1527: Unmatched regex:
I2_Enum is...*badinc-i2.h
I think it's a reasonable trade-off.
-rw-r--r-- | iwyu.cc | 21 | ||||
-rw-r--r-- | tests/cxx/badinc.cc | 3 | ||||
-rw-r--r-- | tests/cxx/stl_container_provides_allocator.cc | 1 |
3 files changed, 22 insertions, 3 deletions
@@ -2552,7 +2552,26 @@ class IwyuBaseAstVisitor : public BaseAstVisitor<Derived> { // If we're in an nns (e.g. the Foo in Foo::bar), we're never // forward-declarable, even if we're part of a pointer type, or in // a template argument, or whatever. - current_ast_node()->set_in_forward_declare_context(false); + ASTNode* ast_node = current_ast_node(); + ast_node->set_in_forward_declare_context(false); + + // For method calls it doesn't matter if a method is defined inside + // a class or outside of it. We detect out-of-class method calls with + // the pattern + // + // CallExpr + // `-CXXMethodDecl + // `-NestedNameSpecifier + // + // and skip traversing method qualifier as in-class methods don't have it. + if (const CXXMethodDecl* parent = ast_node->GetParentAs<CXXMethodDecl>()) { + if ((nns == parent->getQualifier()) && + ast_node->AncestorIsA<CallExpr>(2)) { + VERRS(7) << "Skipping traversal of CXXMethodDecl qualifier " + << PrintableNestedNameSpecifier(nns) << "\n"; + return false; + } + } return true; } diff --git a/tests/cxx/badinc.cc b/tests/cxx/badinc.cc index 921ecc7..c6bd5e2 100644 --- a/tests/cxx/badinc.cc +++ b/tests/cxx/badinc.cc @@ -1844,7 +1844,6 @@ int main() { // IWYU: I1_Class needs a declaration H_TemplateFunction<I1_Class*>(&i1_class); H_TemplateFunction(&i1_class); - // IWYU: I1_Enum is...*badinc-i1.h // IWYU: I22 is...*badinc-i2.h h_templateclass2.static_out_of_line(I22); // IWYU: I22 is...*badinc-i2.h @@ -1947,7 +1946,7 @@ The full include-list for tests/cxx/badinc.cc: #include <fstream> // for fstream #include <list> // for list #include <new> // for operator new -#include <string> // for allocator, basic_string, basic_string<>::iterator, operator+, string +#include <string> // for basic_string, basic_string<>::iterator, operator+, string #include <typeinfo> // for type_info #include "tests/cxx/badinc-d1.h" // for D1CopyClassFn, D1Function, D1_Class, D1_CopyClass, D1_Enum, D1_Enum::D11, D1_I1_Typedef, D1_StructPtr, D1_Subclass, D1_TemplateClass, D1_TemplateStructWithDefaultParam, MACRO_CALLING_I4_FUNCTION #include "tests/cxx/badinc-d4.h" // for D4_ClassForOperator, operator<< diff --git a/tests/cxx/stl_container_provides_allocator.cc b/tests/cxx/stl_container_provides_allocator.cc index 10732aa..aadc1ec 100644 --- a/tests/cxx/stl_container_provides_allocator.cc +++ b/tests/cxx/stl_container_provides_allocator.cc @@ -27,6 +27,7 @@ void foo() { std::uninitialized_fill(buffer, buffer + 4, 0); std::vector<int> v; + (void)v.begin(); } /**** IWYU_SUMMARY |