diff --git a/iwyu.cc b/iwyu.cc index 2715df6..7eba191 100644 --- a/iwyu.cc +++ b/iwyu.cc @@ -4155,7 +4155,15 @@ class IwyuAstConsumer if (ast_node->ParentIsA() || 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; } diff --git a/tests/cxx/dependent_tpl_crash.cc b/tests/cxx/dependent_tpl_crash.cc new file mode 100644 index 0000000..2acaa56 --- /dev/null +++ b/tests/cxx/dependent_tpl_crash.cc @@ -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 +struct ClassValueType {}; + +template +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 + using ClassType = ClassValueType; +}; + +template