r284528 - [c++1z] Fix corner case where we could create a function type whose canonical type is not actually canonical.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 18 13:13:25 PDT 2016
Author: rsmith
Date: Tue Oct 18 15:13:25 2016
New Revision: 284528
URL: http://llvm.org/viewvc/llvm-project?rev=284528&view=rev
Log:
[c++1z] Fix corner case where we could create a function type whose canonical type is not actually canonical.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=284528&r1=284527&r2=284528&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 18 15:13:25 2016
@@ -1224,8 +1224,17 @@ public:
/// \brief Return a normal function type with a typed argument list.
QualType getFunctionType(QualType ResultTy, ArrayRef<QualType> Args,
- const FunctionProtoType::ExtProtoInfo &EPI) const;
+ const FunctionProtoType::ExtProtoInfo &EPI) const {
+ return getFunctionTypeInternal(ResultTy, Args, EPI, false);
+ }
+private:
+ /// \brief Return a normal function type with a typed argument list.
+ QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
+ const FunctionProtoType::ExtProtoInfo &EPI,
+ bool OnlyWantCanonical) const;
+
+public:
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=284528&r1=284527&r2=284528&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 18 15:13:25 2016
@@ -3167,9 +3167,9 @@ static bool isCanonicalExceptionSpecific
return false;
}
-QualType
-ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
- const FunctionProtoType::ExtProtoInfo &EPI) const {
+QualType ASTContext::getFunctionTypeInternal(
+ QualType ResultTy, ArrayRef<QualType> ArgArray,
+ const FunctionProtoType::ExtProtoInfo &EPI, bool OnlyWantCanonical) const {
size_t NumArgs = ArgArray.size();
// Unique functions, to guarantee there is only one function of a particular
@@ -3188,9 +3188,10 @@ ASTContext::getFunctionType(QualType Res
// If we find a pre-existing equivalent FunctionProtoType, we can just reuse
// it so long as our exception specification doesn't contain a dependent
- // noexcept expression. If it /does/, we're going to need to create a type
+ // noexcept expression, or we're just looking for a canonical type.
+ // Otherwise, we're going to need to create a type
// sugar node to hold the concrete expression.
- if (EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
+ if (OnlyWantCanonical || EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())
return Existing;
@@ -3212,6 +3213,10 @@ ASTContext::getFunctionType(QualType Res
if (!ArgArray[i].isCanonicalAsParam())
isCanonical = false;
+ if (OnlyWantCanonical)
+ assert(isCanonical &&
+ "given non-canonical parameters constructing canonical type");
+
// If this type isn't canonical, get the canonical version of it if we don't
// already have it. The exception spec is only partially part of the
// canonical type, and only in C++17 onwards.
@@ -3274,15 +3279,14 @@ ASTContext::getFunctionType(QualType Res
Value.getBoolValue() ? EST_BasicNoexcept : EST_None;
break;
}
- assert(isCanonicalExceptionSpecification(CanonicalEPI.ExceptionSpec,
- NoexceptInType));
} else {
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
}
// Adjust the canonical function result type.
CanQualType CanResultTy = getCanonicalFunctionResultType(ResultTy);
- Canonical = getFunctionType(CanResultTy, CanonicalArgs, CanonicalEPI);
+ Canonical =
+ getFunctionTypeInternal(CanResultTy, CanonicalArgs, CanonicalEPI, true);
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
Modified: 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=284528&r1=284527&r2=284528&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp Tue Oct 18 15:13:25 2016
@@ -12,6 +12,10 @@ template<bool A, bool B> void redecl2()
template<typename A, typename B> void redecl3() throw(A);
template<typename A, typename B> void redecl3() throw(B);
+typedef int I;
+template<bool B> void redecl4(I) noexcept(B);
+template<bool B> void redecl4(I) noexcept(B);
+
namespace DependentDefaultCtorExceptionSpec {
template<typename> struct T { static const bool value = true; };
More information about the cfe-commits
mailing list