hokein created this revision.
hokein added a reviewer: sammccall.
Herald added a project: clang.
hokein edited the summary of this revision.

otherwise we'll run into code path which expects a good base specifiers,
and lead to crashes.

The crash only occurs in template instantiations (in non-template case,
the bad base specifiers are dropped during parsing.)

crash stacktrace:

  clang: llvm-project/clang/lib/Sema/SemaInit.cpp:7864: clang::ExprResult 
clang::InitializationSequence::Perform(clang::Sema &, const 
clang::InitializedEntity &, const clang::InitializationKind &, 
clang::MultiExprArg, clang::QualType *): Assertion `Kind.getKind() == 
InitializationKind::IK_Copy || Kind.isExplicitCast() || Kind.getKind() == 
InitializationKind::IK_DirectList' failed.
  PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash 
backtrace, preprocessed source, and associated run script.
  Stack dump:
  #14 clang::InitializationSequence::Perform(clang::Sema&, 
clang::InitializedEntity const&, clang::InitializationKind const&, 
llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) 
llvm-project/clang/lib/Sema/SemaInit.cpp:7889:12
  #15 BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, 
ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, 
clang::CXXCtorInitializer*&) llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:4563:24
  #16 clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, 
llvm::ArrayRef<clang::CXXCtorInitializer*>) 
llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:5090:11
  #17 clang::Sema::ActOnMemInitializers(clang::Decl*, clang::SourceLocation, 
llvm::ArrayRef<clang::CXXCtorInitializer*>, bool) 
llvm-project/clang/lib/Sema/SemaDeclCXX.cpp:5404:3
  #18 llvm::SmallVectorTemplateCommon<clang::CXXCtorInitializer*, 
void>::isSmall() const llvm-project/llvm/include/llvm/ADT/SmallVector.h:124:39
  #19 llvm::SmallVectorImpl<clang::CXXCtorInitializer*>::~SmallVectorImpl() 
llvm-project/llvm/include/llvm/ADT/SmallVector.h:381:16
  #20 llvm::SmallVector<clang::CXXCtorInitializer*, 4u>::~SmallVector() 
llvm-project/llvm/include/llvm/ADT/SmallVector.h:891:3
  #21 clang::Sema::InstantiateMemInitializers(clang::CXXConstructorDecl*, 
clang::CXXConstructorDecl const*, clang::MultiLevelTemplateArgumentList const&) 
llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:5391:1
  #22 clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, 
clang::FunctionDecl*, bool, bool, bool) 
llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:4699:13
  #23 clang::FunctionDecl::isDefined() const 
llvm-project/clang/include/clang/AST/Decl.h:2035:12
  #24 clang::Sema::PerformPendingInstantiations(bool) 
llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp:5956:23
  #25 llvm::TimeTraceScope::~TimeTraceScope() 
llvm-project/llvm/include/llvm/Support/TimeProfiler.h:86:9
  #26 
clang::Sema::ActOnEndOfTranslationUnitFragment(clang::Sema::TUFragmentKind) 
llvm-project/clang/lib/Sema/Sema.cpp:958:3
  #27 clang::Sema::ActOnEndOfTranslationUnit() 
llvm-project/clang/lib/Sema/Sema.cpp:999:9
  #28 clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, 
bool) llvm-project/clang/lib/Parse/Parser.cpp:657:15


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D82086

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/SemaCXX/invalid-template-base-specifier.cpp


Index: clang/test/SemaCXX/invalid-template-base-specifier.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/invalid-template-base-specifier.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -frecovery-ast -verify %s
+
+bool Foo(int *); // expected-note {{candidate function not viable}}
+
+template <typename T>
+struct Crash : decltype(Foo(T())) { // expected-error {{no matching function 
for call to 'Foo'}}
+  Crash(){};
+};
+
+void test() { Crash<int>(); } // expected-note {{in instantiation of template 
class}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -2426,7 +2426,11 @@
                          TypeSourceInfo *TInfo,
                          SourceLocation EllipsisLoc) {
   QualType BaseType = TInfo->getType();
-
+  if (BaseType->containsErrors()) {
+    // FIXME: should we emit a diagnostic here? We already emit a diagnostic
+    // when parsing the error type.
+    return nullptr;
+  }
   // C++ [class.union]p1:
   //   A union shall not have base classes.
   if (Class->isUnion()) {


Index: clang/test/SemaCXX/invalid-template-base-specifier.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/invalid-template-base-specifier.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -frecovery-ast -verify %s
+
+bool Foo(int *); // expected-note {{candidate function not viable}}
+
+template <typename T>
+struct Crash : decltype(Foo(T())) { // expected-error {{no matching function for call to 'Foo'}}
+  Crash(){};
+};
+
+void test() { Crash<int>(); } // expected-note {{in instantiation of template class}}
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -2426,7 +2426,11 @@
                          TypeSourceInfo *TInfo,
                          SourceLocation EllipsisLoc) {
   QualType BaseType = TInfo->getType();
-
+  if (BaseType->containsErrors()) {
+    // FIXME: should we emit a diagnostic here? We already emit a diagnostic
+    // when parsing the error type.
+    return nullptr;
+  }
   // C++ [class.union]p1:
   //   A union shall not have base classes.
   if (Class->isUnion()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to