Skip to content

Commit

Permalink
Fix detection of substituted tpl param in alias
Browse files Browse the repository at this point in the history
It turns out that the presence of `SubstTemplateTypeParmType` inside
an alias type sugar chain doesn't necessarily mean that it is
a user-provided template parameter. It may occur e. g. when an alias
template is used inside the `typedef` declaration, and its template
parameter is specified inside that declaration. The regression had been
introduced in 2d26dd1 and found on MS STL `vector` implementation
when IWYU started to require `_Simple_types` type info for such a code:

std::vector v{1, 2, 3};
(void)v.begin();

due to the returned `iterator` type alias.
  • Loading branch information
bolshakov-a committed Feb 4, 2024
1 parent 3977b59 commit 827a695
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
5 changes: 5 additions & 0 deletions iwyu_ast_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,11 @@ static bool IsSubstTemplateTypeParmType(const Type* type) {
do {
if (isa<SubstTemplateTypeParmType>(type))
return true;
if (isa<TypedefType>(type) || isa<TemplateSpecializationType>(type)) {
// Still may be substituted outer template parameter but needs additional
// analysis outside this function.
return false;
}
prev_type = type;
type = type->getLocallyUnqualifiedSingleStepDesugaredType().getTypePtr();
} while (type != prev_type);
Expand Down
15 changes: 15 additions & 0 deletions tests/cxx/typedef_chain_no_follow-d4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//===--- typedef_chain_no_follow-d4.h - test input file for iwyu ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "tests/cxx/typedef_chain_class.h"

template <typename T>
using IdentityAlias = T;

using ProvidingWithAliasTpl = IdentityAlias<TypedefChainClass>;
5 changes: 5 additions & 0 deletions tests/cxx/typedef_chain_no_follow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,17 @@
#include "tests/cxx/typedef_chain_no_follow-d1.h"
#include "tests/cxx/typedef_chain_no_follow-d2.h"
#include "tests/cxx/typedef_chain_no_follow-d3.h"
#include "tests/cxx/typedef_chain_no_follow-d4.h"
// Unused include to trigger IWYU summary telling what symbols are used from
// every file.
#include "tests/cxx/direct.h"

void TypedefDeclaredInGlobalNamespace() {
TypedefChainTypedef tct;
tct.Method();

ProvidingWithAliasTpl pwat;
pwat.Method();
}

// Tests how we handle a typedef declared in a class. Main purpose is to make
Expand Down Expand Up @@ -50,5 +54,6 @@ The full include-list for tests/cxx/typedef_chain_no_follow.cc:
#include "tests/cxx/typedef_chain_no_follow-d1.h" // for TypedefChainTypedef
#include "tests/cxx/typedef_chain_no_follow-d2.h" // for NonContainer1
#include "tests/cxx/typedef_chain_no_follow-d3.h" // for NonContainer2
#include "tests/cxx/typedef_chain_no_follow-d4.h" // for ProvidingWithAliasTpl
***** IWYU_SUMMARY */

0 comments on commit 827a695

Please sign in to comment.