Author: Richard Smith Date: 2021-02-04T13:14:15-08:00 New Revision: fcb90cbd3b4ae3934bdd05d538647d37ce899962
URL: https://github.com/llvm/llvm-project/commit/fcb90cbd3b4ae3934bdd05d538647d37ce899962 DIFF: https://github.com/llvm/llvm-project/commit/fcb90cbd3b4ae3934bdd05d538647d37ce899962.diff LOG: Fix miscomputation of dependence for elaborated types that are explicitly qualified as members of the current instantiation. Despite the nested name specifier being fully-dependent in this case, the elaborated type might only be instantiation-dependent, because the type is a member of the current instantiation. Added: Modified: clang/include/clang/AST/DependenceFlags.h clang/include/clang/AST/Type.h clang/test/SemaTemplate/instantiation-dependence.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h index ca96b65574bd..62efdb4ce6e4 100644 --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -128,6 +128,9 @@ class Dependence { // Type depends on a runtime value (variable-length array). VariablyModified = 32, + // Dependence that is propagated syntactically, regardless of semantics. + Syntactic = UnexpandedPack | Instantiation | Error, + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) }; @@ -165,6 +168,13 @@ class Dependence { translate(D, TNDependence::Dependent, Dependent) | translate(D, TNDependence::Error, Error)) {} + /// Extract only the syntactic portions of this type's dependence. + Dependence syntactic() { + Dependence Result = *this; + Result.V &= Syntactic; + return Result; + } + TypeDependence type() const { return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | translate(V, Instantiation, TypeDependence::Instantiation) | @@ -256,6 +266,10 @@ inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { return Dependence(D).type(); } +inline TypeDependence toSyntacticDependence(TypeDependence D) { + return Dependence(D).syntactic().type(); +} + inline NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D) { return Dependence(D).nestedNameSpecifier(); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 319d3850346b..66ed32a9e9e5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -5412,8 +5412,13 @@ class ElaboratedType final ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) : TypeWithKeyword(Keyword, Elaborated, CanonType, + // Any semantic dependence on the qualifier will have + // been incorporated into NamedType. We still need to + // track syntactic (instantiation / error / pack) + // dependence on the qualifier. NamedType->getDependence() | - (NNS ? toTypeDependence(NNS->getDependence()) + (NNS ? toSyntacticDependence( + toTypeDependence(NNS->getDependence())) : TypeDependence::None)), NNS(NNS), NamedType(NamedType) { ElaboratedTypeBits.HasOwnedTagDecl = false; diff --git a/clang/test/SemaTemplate/instantiation-dependence.cpp b/clang/test/SemaTemplate/instantiation-dependence.cpp index 2b9a47ad25a4..ae641080bec0 100644 --- a/clang/test/SemaTemplate/instantiation-dependence.cpp +++ b/clang/test/SemaTemplate/instantiation-dependence.cpp @@ -80,3 +80,24 @@ namespace TypeQualifier { template<typename T> A<sizeof(sizeof(T::error))>::type f() {} // expected-note {{'int' cannot be used prior to '::'}} int k = f<int>(); // expected-error {{no matching}} } + +namespace MemberOfInstantiationDependentBase { + template<typename T> struct A { template<int> void f(int); }; + template<typename T> struct B { using X = A<T>; }; + template<typename T> struct C1 : B<int> { + using X = typename C1::X; + void f(X *p) { + p->f<0>(0); + p->template f<0>(0); + } + }; + template<typename T> struct C2 : B<int> { + using X = typename C2<T>::X; + void f(X *p) { + p->f<0>(0); + p->template f<0>(0); + } + }; + void q(C1<int> *c) { c->f(0); } + void q(C2<int> *c) { c->f(0); } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits