Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on invalid: ResolveSingleFunctionTemplateSpecialization #48673

Closed
hokein opened this issue Feb 23, 2021 · 3 comments · Fixed by #89019
Closed

Crash on invalid: ResolveSingleFunctionTemplateSpecialization #48673

hokein opened this issue Feb 23, 2021 · 3 comments · Fixed by #89019
Labels
bugzilla Issues migrated from bugzilla c++ clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-invalid

Comments

@hokein
Copy link
Collaborator

hokein commented Feb 23, 2021

Bugzilla Link 49329
Version trunk
OS All
CC @DougGregor,@zygoloid

Extended Description

Testcase:

template <typename T>
class C {
public:
  template<int TT>
  class Type {
  };
};

template <typename T1>
class A {
public:
  void foo() {
    C<T1>::template Type<2>;
  }
};

void test() {
    A<float> a;
    a.foo();
}

Crash stack trace:

clang: llvm-project/llvm/include/llvm/Support/Casting.h:269: typename cast_retty<X, Y *>::ret_type llvm::cast(Y *) [X = clang::FunctionTemplateDecl, Y = clang::NamedDecl]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: ./bin/clang -cc1 -ast-dump /tmp/t1.cpp
1.      <eof> parser at end of file
2.      /tmp/t1.cpp:13:8: instantiating function definition 'A<float>::foo'
 #&#8203;0 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) llvm-project/llvm/lib/Support/Unix/Signals.inc:565:11
 #&#8203;1 PrintStackTraceSignalHandler(void*) llvm-project/llvm/lib/Support/Unix/Signals.inc:632:1
 #&#8203;2 llvm::sys::RunSignalHandlers() llvm-project/llvm/lib/Support/Signals.cpp:70:5
 #&#8203;3 SignalHandler(int) llvm-project/llvm/lib/Support/Unix/Signals.inc:407:1
 #&#8203;4 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14140)
 #&#8203;5 raise ./signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #&#8203;6 abort ./stdlib/abort.c:81:7
 #&#8203;7 get_sysdep_segment_value ./intl/loadmsgcat.c:509:8
 #&#8203;8 _nl_load_domain ./intl/loadmsgcat.c:970:34
 #&#8203;9 (/lib/x86_64-linux-gnu/libc.so.6+0x34662)
#&#8203;10 llvm::cast_retty<clang::FunctionTemplateDecl, clang::NamedDecl*>::ret_type llvm::cast<clang::FunctionTemplateDecl, clang::NamedDecl>(clang::NamedDecl*) llvm-project/llvm/include/llvm/Support/Casting.h:270:10
#&#8203;11 clang::Sema::ResolveSingleFunctionTemplateSpecialization(clang::OverloadExpr*, bool, clang::DeclAccessPair*) llvm-project/clang/lib/Sema/SemaOverload.cpp:12460:27
#&#8203;12 clang::Sema::ResolveAndFixSingleFunctionTemplateSpecialization(clang::ActionResult<clang::Expr*, true>&, bool, bool, clang::SourceRange, clang::QualType, unsigned int) llvm-project/clang/lib/Sema/SemaOverload.cpp:12525:21
#&#8203;13 clang::Sema::CheckPlaceholderExpr(clang::Expr*) llvm-project/clang/lib/Sema/SemaExpr.cpp:19272:9
#&#8203;14 clang::Sema::ActOnFinishFullExpr(clang::Expr*, clang::SourceLocation, bool, bool) llvm-project/clang/lib/Sema/SemaExprCXX.cpp:8388:16
#&#8203;15 clang::Sema::ActOnExprStmt(clang::ActionResult<clang::Expr*, true>, bool) llvm-project/clang/lib/Sema/SemaStmt.cpp:49:8
#&#8203;16 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformStmt(clang::Stmt*, clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::StmtDiscardKind) llvm-project/clang/lib/Sema/TreeTransform.h:3687:24
#&#8203;17 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) llvm-project/clang/lib/Sema/TreeTransform.h:7109:38
#&#8203;18 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*) llvm-project/clang/lib/Sema/TreeTransform.h:7095:23
#&#8203;19 clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformStmt(clang::Stmt*, clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::StmtDiscardKind) llvm-project/build-debug/tools/clang/include/clang/AST/StmtNodes.inc:73:1
#&#8203;20 clang::Sema::SubstStmt(clang::Stmt*, clang::MultiLevelTemplateArgumentList const&) llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp:3460:23
#&#8203;21 clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:4892:14
#&#8203;22 clang::Sema::PerformPendingInstantiations(bool) llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:6139:13
#&#8203;23 clang::Sema::ActOnEndOfTranslationUnitFragment(clang::Sema::TUFragmentKind) llvm-project/clang/lib/Sema/Sema.cpp:995:3
#&#8203;24 clang::Sema::ActOnEndOfTranslationUnit() llvm-project/clang/lib/Sema/Sema.cpp:1030:5

Looks like this is a regression, it is in trunk, but not reproducible in clang-11.0.1.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 11, 2021
@shafik
Copy link
Collaborator

shafik commented Feb 9, 2023

confirmed, godbolt: https://godbolt.org/z/YWWMqqMza

@shafik shafik added the confirmed Verified by a second party label Feb 9, 2023
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" crash Prefer [crash-on-valid] or [crash-on-invalid] labels Feb 9, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Feb 9, 2023

@llvm/issue-subscribers-clang-frontend

@shafik shafik added crash-on-invalid and removed crash Prefer [crash-on-valid] or [crash-on-invalid] labels Feb 9, 2023
@shafik
Copy link
Collaborator

shafik commented Feb 9, 2023

Might be related to: #58301

zyn0217 added a commit to zyn0217/llvm-project that referenced this issue Apr 17, 2024
This patch revolves around the misuse of UnresolvedLookupExpr in
BuildTemplateIdExpr.

Basically, we build up an UnresolvedLookupExpr not only for function
overloads but for "unresolved" templates wherever we need an expression
for template decls. For example, a dependent VarTemplateDecl can be
wrapped with such an expression before template instantiation. (See
llvm@6170072)

Also, one important thing is that UnresolvedLookupExpr uses a "canonical"
QualType to describe the containing unresolved decls: a DependentTy is
for dependent expressions and an OverloadTy otherwise. Therefore, this
modeling for non-dependent templates leaves a problem in that the expression
is marked and perceived as if describing overload functions. The consumer then
expects functions for every such expression, although the fact is the reverse.
Hence, we run into crashes.

As to the patch, I added a new canonical type "UnresolvedTemplateTy" to
model these cases. Given that we have been using this model (intentionally or
accidentally) and it is pretty baked in throughout the code, I think
extending the role of UnresolvedLookupExpr is reasonable. Further, I added
some diagnostics for the direct occurrence of these expressions, which
are supposed to be ill-formed.

As a bonus, this patch also fixes some typos in the diagnostics and creates
RecoveryExprs rather than nothing in the hope of a better error-recovery
for clangd.

Fixes llvm#88832
Fixes llvm#63243
Fixes llvm#48673
@zyn0217 zyn0217 closed this as completed in 7a484d3 May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla c++ clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party crash-on-invalid
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants