Author: rsmith Date: Tue Oct 18 01:47:03 2016 New Revision: 284457 URL: http://llvm.org/viewvc/llvm-project?rev=284457&view=rev Log: [c++1z] Use canonical expression equivalence to determine whether two different dependent noexcept specifications result in the same canonical function type.
We still use non-canonical hashing when deduplicating type sugar so that diagnostics will point to the right place. Added: cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp Modified: cfe/trunk/include/clang/AST/Type.h cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/AST/Type.cpp Modified: cfe/trunk/include/clang/AST/Type.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=284457&r1=284456&r2=284457&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/Type.h (original) +++ cfe/trunk/include/clang/AST/Type.h Tue Oct 18 01:47:03 2016 @@ -3473,7 +3473,8 @@ public: void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, param_type_iterator ArgTys, unsigned NumArgs, - const ExtProtoInfo &EPI, const ASTContext &Context); + const ExtProtoInfo &EPI, const ASTContext &Context, + bool Canonical); }; /// \brief Represents the dependent type named by a dependently-scoped Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=284457&r1=284456&r2=284457&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 18 01:47:03 2016 @@ -3170,17 +3170,6 @@ ASTContext::getFunctionType(QualType Res const FunctionProtoType::ExtProtoInfo &EPI) const { size_t NumArgs = ArgArray.size(); - // Unique functions, to guarantee there is only one function of a particular - // structure. - llvm::FoldingSetNodeID ID; - FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI, - *this); - - void *InsertPos = nullptr; - if (FunctionProtoType *FTP = - FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(FTP, 0); - bool NoexceptInType = getLangOpts().CPlusPlus1z; bool IsCanonicalExceptionSpec = @@ -3193,6 +3182,17 @@ ASTContext::getFunctionType(QualType Res if (!ArgArray[i].isCanonicalAsParam()) isCanonical = false; + // Unique functions, to guarantee there is only one function of a particular + // structure. + llvm::FoldingSetNodeID ID; + FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI, + *this, isCanonical); + + void *InsertPos = nullptr; + if (FunctionProtoType *FTP = + FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos)) + return QualType(FTP, 0); + // If this type isn't canonical, get the canonical version of it. // The exception spec is not part of the canonical type. QualType Canonical; Modified: cfe/trunk/lib/AST/Type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=284457&r1=284456&r2=284457&view=diff ============================================================================== --- cfe/trunk/lib/AST/Type.cpp (original) +++ cfe/trunk/lib/AST/Type.cpp Tue Oct 18 01:47:03 2016 @@ -2850,7 +2850,7 @@ bool FunctionProtoType::isTemplateVariad void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, const QualType *ArgTys, unsigned NumParams, const ExtProtoInfo &epi, - const ASTContext &Context) { + const ASTContext &Context, bool Canonical) { // We have to be careful not to get ambiguous profile encodings. // Note that valid type pointers are never ambiguous with anything else. @@ -2889,7 +2889,7 @@ void FunctionProtoType::Profile(llvm::Fo ID.AddPointer(Ex.getAsOpaquePtr()); } else if (epi.ExceptionSpec.Type == EST_ComputedNoexcept && epi.ExceptionSpec.NoexceptExpr) { - epi.ExceptionSpec.NoexceptExpr->Profile(ID, Context, false); + epi.ExceptionSpec.NoexceptExpr->Profile(ID, Context, Canonical); } else if (epi.ExceptionSpec.Type == EST_Uninstantiated || epi.ExceptionSpec.Type == EST_Unevaluated) { ID.AddPointer(epi.ExceptionSpec.SourceDecl->getCanonicalDecl()); @@ -2905,7 +2905,7 @@ void FunctionProtoType::Profile(llvm::Fo void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { Profile(ID, getReturnType(), param_type_begin(), NumParams, getExtProtoInfo(), - Ctx); + Ctx, isCanonicalUnqualified()); } QualType TypedefType::desugar() const { Added: cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp?rev=284457&view=auto ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp (added) +++ cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp Tue Oct 18 01:47:03 2016 @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++1z -verify %s + +template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-note {{previous}} +template<typename T> void redecl1() noexcept(noexcept(T())); // ok, same type +template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-error {{redefinition}} + +template<bool A, bool B> void redecl2() noexcept(A); // expected-note {{previous}} +template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{conflicting types}} + +// These have the same canonical type. +// FIXME: It's not clear whether this is supposed to be valid. +template<typename A, typename B> void redecl3() throw(A); +template<typename A, typename B> void redecl3() throw(B); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits