Sorry, the repro link should've pointed to https://bugs.chromium.org/p/chromium/issues/detail?id=1110981#c22 which has a nicer stack.
On Fri, Jul 31, 2020 at 7:22 PM Nico Weber <tha...@chromium.org> wrote: > Heads-up: This causes Chromium's build to fail with > > clang-cl: > /usr/local/google/home/thakis/src/chrome/src/third_party/llvm/clang/lib/AST/ASTContext.cpp:4823: > clang::QualType clang::ASTContext::getPackExpansionType(clang::QualType, > llvm::Optional<unsigned int>, bool): Assertion `(!ExpectPackInType || > Pattern->containsUnexpandedParameterPack()) && "Pack expansions must expand > one or more parameter packs"' failed. > > under certain scenarios with precompiled headers. At the moment I only > have a repro when we use a Chromium-specific compiler plugin ( > https://bugs.chromium.org/p/chromium/issues/detail?id=1110981#c19), but > it's likely I'll have one without that soonish. > > On Tue, Jul 28, 2020 at 4:23 PM Richard Smith via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> >> Author: Richard Smith >> Date: 2020-07-28T13:23:13-07:00 >> New Revision: 740a164dec483225cbd02ab6c82199e2747ffacb >> >> URL: >> https://github.com/llvm/llvm-project/commit/740a164dec483225cbd02ab6c82199e2747ffacb >> DIFF: >> https://github.com/llvm/llvm-project/commit/740a164dec483225cbd02ab6c82199e2747ffacb.diff >> >> LOG: PR46377: Fix dependence calculation for function types and typedef >> types. >> >> We previously did not treat a function type as dependent if it had a >> parameter pack with a non-dependent type -- such a function type depends >> on the arity of the pack so is dependent even though none of the >> parameter types is dependent. In order to properly handle this, we now >> treat pack expansion types as always being dependent types (depending on >> at least the pack arity), and always canonically being pack expansion >> types, even in the unusual case when the pattern is not a dependent >> type. This does mean that we can have canonical types that are pack >> expansions that contain no unexpanded packs, which is unfortunate but >> not inaccurate. >> >> We also previously did not treat a typedef type as >> instantiation-dependent if its canonical type was not >> instantiation-dependent. That's wrong because instantiation-dependence >> is a property of the type sugar, not of the type; an >> instantiation-dependent type can have a non-instantiation-dependent >> canonical type. >> >> Added: >> clang/test/SemaTemplate/alias-template-nondependent.cpp >> >> Modified: >> clang/include/clang/AST/ASTContext.h >> clang/include/clang/AST/Type.h >> clang/include/clang/Basic/TypeNodes.td >> clang/lib/AST/ASTContext.cpp >> clang/lib/AST/Type.cpp >> clang/lib/CodeGen/CGDebugInfo.cpp >> clang/lib/CodeGen/CodeGenFunction.cpp >> clang/lib/Sema/SemaExpr.cpp >> clang/lib/Sema/SemaLambda.cpp >> clang/lib/Sema/SemaTemplateVariadic.cpp >> clang/lib/Sema/SemaType.cpp >> >> Removed: >> >> >> >> >> ################################################################################ >> diff --git a/clang/include/clang/AST/ASTContext.h >> b/clang/include/clang/AST/ASTContext.h >> index 59e2679ddded..6c00fe86f282 100644 >> --- a/clang/include/clang/AST/ASTContext.h >> +++ b/clang/include/clang/AST/ASTContext.h >> @@ -1459,8 +1459,16 @@ class ASTContext : public >> RefCountedBase<ASTContext> { >> void getInjectedTemplateArgs(const TemplateParameterList *Params, >> SmallVectorImpl<TemplateArgument> &Args); >> >> + /// Form a pack expansion type with the given pattern. >> + /// \param NumExpansions The number of expansions for the pack, if >> known. >> + /// \param ExpectPackInType If \c false, we should not expect \p >> Pattern to >> + /// contain an unexpanded pack. This only makes sense if the >> pack >> + /// expansion is used in a context where the arity is inferred >> from >> + /// elsewhere, such as if the pattern contains a placeholder >> type or >> + /// if this is the canonical type of another pack expansion >> type. >> QualType getPackExpansionType(QualType Pattern, >> - Optional<unsigned> NumExpansions); >> + Optional<unsigned> NumExpansions, >> + bool ExpectPackInType = true); >> >> QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, >> ObjCInterfaceDecl *PrevDecl = nullptr) >> const; >> >> diff --git a/clang/include/clang/AST/Type.h >> b/clang/include/clang/AST/Type.h >> index 9a745ef20fac..7fe652492b0e 100644 >> --- a/clang/include/clang/AST/Type.h >> +++ b/clang/include/clang/AST/Type.h >> @@ -4383,11 +4383,7 @@ class TypedefType : public Type { >> protected: >> friend class ASTContext; // ASTContext creates these. >> >> - TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) >> - : Type(tc, can, can->getDependence() & >> ~TypeDependence::UnexpandedPack), >> - Decl(const_cast<TypedefNameDecl *>(D)) { >> - assert(!isa<TypedefType>(can) && "Invalid canonical type"); >> - } >> + TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can); >> >> public: >> TypedefNameDecl *getDecl() const { return Decl; } >> @@ -5624,7 +5620,8 @@ class PackExpansionType : public Type, public >> llvm::FoldingSetNode { >> PackExpansionType(QualType Pattern, QualType Canon, >> Optional<unsigned> NumExpansions) >> : Type(PackExpansion, Canon, >> - (Pattern->getDependence() | TypeDependence::Instantiation) & >> + (Pattern->getDependence() | TypeDependence::Dependent | >> + TypeDependence::Instantiation) & >> ~TypeDependence::UnexpandedPack), >> Pattern(Pattern) { >> PackExpansionTypeBits.NumExpansions = >> @@ -5645,8 +5642,8 @@ class PackExpansionType : public Type, public >> llvm::FoldingSetNode { >> return None; >> } >> >> - bool isSugared() const { return !Pattern->isDependentType(); } >> - QualType desugar() const { return isSugared() ? Pattern : >> QualType(this, 0); } >> + bool isSugared() const { return false; } >> + QualType desugar() const { return QualType(this, 0); } >> >> void Profile(llvm::FoldingSetNodeID &ID) { >> Profile(ID, getPattern(), getNumExpansions()); >> >> diff --git a/clang/include/clang/Basic/TypeNodes.td >> b/clang/include/clang/Basic/TypeNodes.td >> index a4e3002b9075..011394c3ef45 100644 >> --- a/clang/include/clang/Basic/TypeNodes.td >> +++ b/clang/include/clang/Basic/TypeNodes.td >> @@ -100,7 +100,7 @@ def DeducedTemplateSpecializationType : >> TypeNode<DeducedType>; >> def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType; >> def DependentNameType : TypeNode<Type>, AlwaysDependent; >> def DependentTemplateSpecializationType : TypeNode<Type>, >> AlwaysDependent; >> -def PackExpansionType : TypeNode<Type>, NeverCanonicalUnlessDependent; >> +def PackExpansionType : TypeNode<Type>, AlwaysDependent; >> def ObjCTypeParamType : TypeNode<Type>, NeverCanonical; >> def ObjCObjectType : TypeNode<Type>; >> def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType; >> >> diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp >> index e7518a538fe6..25bf71519d1c 100644 >> --- a/clang/lib/AST/ASTContext.cpp >> +++ b/clang/lib/AST/ASTContext.cpp >> @@ -4817,37 +4817,27 @@ ASTContext::getInjectedTemplateArgs(const >> TemplateParameterList *Params, >> } >> >> QualType ASTContext::getPackExpansionType(QualType Pattern, >> - Optional<unsigned> >> NumExpansions) { >> + Optional<unsigned> >> NumExpansions, >> + bool ExpectPackInType) { >> + assert((!ExpectPackInType || >> Pattern->containsUnexpandedParameterPack()) && >> + "Pack expansions must expand one or more parameter packs"); >> + >> llvm::FoldingSetNodeID ID; >> PackExpansionType::Profile(ID, Pattern, NumExpansions); >> >> - // A deduced type can deduce to a pack, eg >> - // auto ...x = some_pack; >> - // That declaration isn't (yet) valid, but is created as part of >> building an >> - // init-capture pack: >> - // [...x = some_pack] {} >> - assert((Pattern->containsUnexpandedParameterPack() || >> - Pattern->getContainedDeducedType()) && >> - "Pack expansions must expand one or more parameter packs"); >> void *InsertPos = nullptr; >> - PackExpansionType *T >> - = PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); >> + PackExpansionType *T = PackExpansionTypes.FindNodeOrInsertPos(ID, >> InsertPos); >> if (T) >> return QualType(T, 0); >> >> QualType Canon; >> if (!Pattern.isCanonical()) { >> - Canon = getCanonicalType(Pattern); >> - // The canonical type might not contain an unexpanded parameter >> pack, if it >> - // contains an alias template specialization which ignores one of its >> - // parameters. >> - if (Canon->containsUnexpandedParameterPack()) { >> - Canon = getPackExpansionType(Canon, NumExpansions); >> - >> - // Find the insert position again, in case we inserted an element >> into >> - // PackExpansionTypes and invalidated our insert position. >> - PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); >> - } >> + Canon = getPackExpansionType(getCanonicalType(Pattern), >> NumExpansions, >> + /*ExpectPackInType=*/false); >> + >> + // Find the insert position again, in case we inserted an element >> into >> + // PackExpansionTypes and invalidated our insert position. >> + PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos); >> } >> >> T = new (*this, TypeAlignment) >> >> diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp >> index 0122d2e7de52..d40ba4c648c4 100644 >> --- a/clang/lib/AST/Type.cpp >> +++ b/clang/lib/AST/Type.cpp >> @@ -1187,9 +1187,6 @@ struct SimpleTransformVisitor : public >> TypeVisitor<Derived, QualType> { >> T->getTypeConstraintArguments()); >> } >> >> - // FIXME: Non-trivial to implement, but important for C++ >> - SUGARED_TYPE_CLASS(PackExpansion) >> - >> QualType VisitObjCObjectType(const ObjCObjectType *T) { >> QualType baseType = recurse(T->getBaseType()); >> if (baseType.isNull()) >> @@ -3348,6 +3345,12 @@ void >> FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, >> getExtProtoInfo(), Ctx, isCanonicalUnqualified()); >> } >> >> +TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D, >> QualType can) >> + : Type(tc, can, D->getUnderlyingType()->getDependence()), >> + Decl(const_cast<TypedefNameDecl *>(D)) { >> + assert(!isa<TypedefType>(can) && "Invalid canonical type"); >> +} >> + >> QualType TypedefType::desugar() const { >> return getDecl()->getUnderlyingType(); >> } >> >> diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp >> b/clang/lib/CodeGen/CGDebugInfo.cpp >> index 6965c4a1209c..780e0c692c05 100644 >> --- a/clang/lib/CodeGen/CGDebugInfo.cpp >> +++ b/clang/lib/CodeGen/CGDebugInfo.cpp >> @@ -3252,7 +3252,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType >> Ty, llvm::DIFile *Unit) { >> case Type::TypeOf: >> case Type::Decltype: >> case Type::UnaryTransform: >> - case Type::PackExpansion: >> break; >> } >> >> >> diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp >> b/clang/lib/CodeGen/CodeGenFunction.cpp >> index 8ce488f35dd3..8f79cc77f0e6 100644 >> --- a/clang/lib/CodeGen/CodeGenFunction.cpp >> +++ b/clang/lib/CodeGen/CodeGenFunction.cpp >> @@ -2075,7 +2075,6 @@ void >> CodeGenFunction::EmitVariablyModifiedType(QualType type) { >> case Type::UnaryTransform: >> case Type::Attributed: >> case Type::SubstTemplateTypeParm: >> - case Type::PackExpansion: >> case Type::MacroQualified: >> // Keep walking after single level desugaring. >> type = type.getSingleStepDesugaredType(getContext()); >> >> diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp >> index 21d3bbf419a9..bb0b1fa49851 100644 >> --- a/clang/lib/Sema/SemaExpr.cpp >> +++ b/clang/lib/Sema/SemaExpr.cpp >> @@ -4345,7 +4345,6 @@ static void captureVariablyModifiedType(ASTContext >> &Context, QualType T, >> case Type::UnaryTransform: >> case Type::Attributed: >> case Type::SubstTemplateTypeParm: >> - case Type::PackExpansion: >> case Type::MacroQualified: >> // Keep walking after single level desugaring. >> T = T.getSingleStepDesugaredType(Context); >> >> diff --git a/clang/lib/Sema/SemaLambda.cpp >> b/clang/lib/Sema/SemaLambda.cpp >> index 657ed13f207a..dc74f6e2f7dc 100644 >> --- a/clang/lib/Sema/SemaLambda.cpp >> +++ b/clang/lib/Sema/SemaLambda.cpp >> @@ -803,7 +803,8 @@ QualType Sema::buildLambdaInitCaptureInitialization( >> Diag(EllipsisLoc, getLangOpts().CPlusPlus20 >> ? diag::warn_cxx17_compat_init_capture_pack >> : diag::ext_init_capture_pack); >> - DeductType = Context.getPackExpansionType(DeductType, >> NumExpansions); >> + DeductType = Context.getPackExpansionType(DeductType, >> NumExpansions, >> + >> /*ExpectPackInType=*/false); >> >> TLB.push<PackExpansionTypeLoc>(DeductType).setEllipsisLoc(EllipsisLoc); >> } else { >> // Just ignore the ellipsis for now and form a non-pack variable. >> We'll >> >> diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp >> b/clang/lib/Sema/SemaTemplateVariadic.cpp >> index 7b77d1cb482a..259cc5165776 100644 >> --- a/clang/lib/Sema/SemaTemplateVariadic.cpp >> +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp >> @@ -614,7 +614,8 @@ QualType Sema::CheckPackExpansion(QualType Pattern, >> SourceRange PatternRange, >> return QualType(); >> } >> >> - return Context.getPackExpansionType(Pattern, NumExpansions); >> + return Context.getPackExpansionType(Pattern, NumExpansions, >> + /*ExpectPackInType=*/false); >> } >> >> ExprResult Sema::ActOnPackExpansion(Expr *Pattern, SourceLocation >> EllipsisLoc) { >> >> diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp >> index 3eabe7ca6ffe..4c7eece68bca 100644 >> --- a/clang/lib/Sema/SemaType.cpp >> +++ b/clang/lib/Sema/SemaType.cpp >> @@ -5516,7 +5516,7 @@ static TypeSourceInfo >> *GetFullTypeForDeclarator(TypeProcessingState &state, >> << T << D.getSourceRange(); >> D.setEllipsisLoc(SourceLocation()); >> } else { >> - T = Context.getPackExpansionType(T, None); >> + T = Context.getPackExpansionType(T, None, >> /*ExpectPackInType=*/false); >> } >> break; >> case DeclaratorContext::TemplateParamContext: >> >> diff --git a/clang/test/SemaTemplate/alias-template-nondependent.cpp >> b/clang/test/SemaTemplate/alias-template-nondependent.cpp >> new file mode 100644 >> index 000000000000..e8ea16483a09 >> --- /dev/null >> +++ b/clang/test/SemaTemplate/alias-template-nondependent.cpp >> @@ -0,0 +1,24 @@ >> +// RUN: %clang_cc1 -std=c++20 -verify %s >> + >> +namespace PR46377 { >> + template<typename> using IntPtr = int*; >> + template<typename ...T> auto non_dependent_typedef() { >> + typedef int(*P)(IntPtr<T>...); >> + return P(); >> + } >> + template<typename ...T> auto non_dependent_alias() { >> + using P = int(*)(IntPtr<T>...); >> + return P(); >> + } >> + template<typename ...T> auto non_dependent_via_sizeof() { >> + using P = int(*)(int(...pack)[sizeof(sizeof(T))]); // expected-error >> {{invalid application of 'sizeof'}} >> + return P(); >> + } >> + >> + using a = int (*)(int*, int*); >> + using a = decltype(non_dependent_typedef<void, void>()); >> + using a = decltype(non_dependent_alias<void, void>()); >> + using a = decltype(non_dependent_via_sizeof<float, float>()); >> + >> + using b = decltype(non_dependent_via_sizeof<float, void>()); // >> expected-note {{instantiation of}} >> +} >> >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits