From: Haojian Wu Date: Wed, 24 Jun 2020 14:14:34 +0000 (+0200) Subject: [AST][RecoveryExpr] Add error-bit TemplateArgument X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5f94c9a421ec7cc7ece2bd875e010639ee0783ec;p=platform%2Fupstream%2Fllvm.git [AST][RecoveryExpr] Add error-bit TemplateArgument Summary: We are missing the error-bit somehow if the error-bit is propagated through the code path: "error type/expr" -> "template argument" -> "template specialization type", which will lead to crashes. Reviewers: sammccall Reviewed By: sammccall Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D82102 --- diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index 54e12ea..7e04486 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -64,6 +64,23 @@ struct TypeDependenceScope { }; using TypeDependence = TypeDependenceScope::TypeDependence; +struct TemplateArgumentDependenceScope { + enum TemplateArgumentDependence : uint8_t { + UnexpandedPack = 1, + Instantiation = 2, + Dependent = 4, + + Error = 8, + + DependentInstantiation = Dependent | Instantiation, + None = 0, + All = 15, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) + }; +}; +using TemplateArgumentDependence = + TemplateArgumentDependenceScope ::TemplateArgumentDependence; + #define LLVM_COMMON_DEPENDENCE(NAME) \ struct NAME##Scope { \ enum NAME : uint8_t { \ @@ -82,7 +99,6 @@ using TypeDependence = TypeDependenceScope::TypeDependence; LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) LLVM_COMMON_DEPENDENCE(TemplateNameDependence) -LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) #undef LLVM_COMMON_DEPENDENCE // A combined space of all dependence concepts for all node types. @@ -137,8 +153,9 @@ public: Dependence(TemplateArgumentDependence D) : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) | - translate(D, TADependence::Instantiation, Instantiation) | - translate(D, TADependence::Dependent, Dependent)) {} + translate(D, TADependence::Instantiation, Instantiation) | + translate(D, TADependence::Dependent, Dependent) | + translate(D, TADependence::Error, Error)) {} Dependence(TemplateNameDependence D) : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) | @@ -170,7 +187,8 @@ public: TemplateArgumentDependence templateArgument() const { return translate(V, UnexpandedPack, TADependence::UnexpandedPack) | translate(V, Instantiation, TADependence::Instantiation) | - translate(V, Dependent, TADependence::Dependent); + translate(V, Dependent, TADependence::Dependent) | + translate(V, Error, TADependence::Error); } TemplateNameDependence templateName() const { diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ba0d86b..05962f3 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3591,7 +3591,7 @@ TemplateSpecializationType::TemplateSpecializationType( auto *TemplateArgs = reinterpret_cast(this + 1); for (const TemplateArgument &Arg : Args) { - // Update instantiation-dependent and variably-modified bits. + // Update instantiation-dependent, variably-modified, and error bits. // If the canonical type exists and is non-dependent, the template // specialization type can be non-dependent even if one of the type // arguments is. Given: diff --git a/clang/test/SemaCXX/invalid-template-base-specifier.cpp b/clang/test/SemaCXX/invalid-template-base-specifier.cpp index c0f5aab..7a1a7f8 100644 --- a/clang/test/SemaCXX/invalid-template-base-specifier.cpp +++ b/clang/test/SemaCXX/invalid-template-base-specifier.cpp @@ -1,7 +1,6 @@ // RUN: %clang_cc1 -frecovery-ast -verify %s -bool Foo(int *); // expected-note {{candidate function not viable}} \ - // expected-note {{candidate function not viable}} +bool Foo(int *); // expected-note 3{{candidate function not viable}} template struct Crash : decltype(Foo(T())) { // expected-error {{no matching function for call to 'Foo'}} @@ -18,3 +17,12 @@ struct Crash2 : decltype(Alias()) { // expected-note {{in instantiation of te }; void test2() { Crash2(); } // expected-note {{in instantiation of template class 'Crash2' requested here}} + +template +class Base {}; +template +struct Crash3 : Base { // expected-error {{no matching function for call to 'Foo'}} + Crash3(){}; +}; + +void test3() { Crash3(); } // expected-note {{in instantiation of template class}}