Work around dependent template alias crash

Only attempt to report decl uses of template names that have an
underlying template decl. This ignores uses of dependent templates and
potentially other such variations.

Even if that causes us to miss reporting for some valid constructs, it
allows further analysis of files that would otherwise crash IWYU.

Fixes issue #1140
This commit is contained in:
Kim Gräsman 2022-11-25 21:55:04 +01:00
parent 44444960dc
commit 68646a5efd
2 changed files with 57 additions and 1 deletions

10
iwyu.cc
View File

@ -4155,7 +4155,15 @@ class IwyuAstConsumer
if (ast_node->ParentIsA<DeducedTemplateSpecializationType>() ||
IsDefaultTemplateTemplateArg(ast_node)) {
current_ast_node()->set_in_forward_declare_context(false);
ReportDeclUse(CurrentLoc(), template_name.getAsTemplateDecl());
// Not all template name kinds have an associated template decl; notably
// dependent names, overloaded template names and ADL-resolved names. Only
// report the use if we can find a decl.
if (TemplateDecl* template_decl = template_name.getAsTemplateDecl()) {
ReportDeclUse(CurrentLoc(), template_decl);
} else {
// TODO: There should probably be handling of these delayed-resolution
// template decls as well, but probably not here.
}
}
return true;
}

View File

@ -0,0 +1,48 @@
//===--- dependent_tpl_crash.cc - 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.
//
//===----------------------------------------------------------------------===//
// Tests that we don't trigger an assertion failure for dependent template
// aliases. We avoid reporting uses of template names without an underlying
// template decl to ensure we don't hit this.
template <int value, typename Type>
struct ClassValueType {};
template <int value>
struct ClassValue {
// This would fail with:
// Assertion failed: Val && "isa<> used on a null pointer"
// because a dependent template alias does not have an underlying template
// decl.
template <typename Type>
using ClassType = ClassValueType<value, Type>;
};
template <template <typename> typename TemplateClassType>
struct FinalType {
static void run() {
TemplateClassType<int> instance{};
}
};
template <int value>
void test() {
using Type = FinalType<ClassValue<value>::template ClassType>;
Type::run();
}
int main() {
test<0>();
}
/**** IWYU_SUMMARY
(tests/cxx/dependent_tpl_crash.cc has correct #includes/fwd-decls)
***** IWYU_SUMMARY */