r217995 - Instantiate exception specifications when instantiating function types (other
Alexander Kornienko
alexfh at google.com
Thu Sep 18 07:32:20 PDT 2014
On Thu, Sep 18, 2014 at 1:57 AM, Richard Smith <richard-llvm at metafoo.co.uk>
wrote:
> Author: rsmith
> Date: Wed Sep 17 18:57:05 2014
> New Revision: 217995
>
> URL: http://llvm.org/viewvc/llvm-project?rev=217995&view=rev
> Log:
> Instantiate exception specifications when instantiating function types
> (other
> than the type of a function declaration). We previously didn't instantiate
> these at all! This also covers the pathological case where the only
> mention of
> a parameter pack is within the exception specification; this gives us a
> second
> way (other than alias templates) to reach the horrible state where a type
> contains an unexpanded pack, but its canonical type does not.
>
> Modified:
> cfe/trunk/include/clang/AST/DataRecursiveASTVisitor.h
> cfe/trunk/include/clang/AST/Expr.h
> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> cfe/trunk/include/clang/AST/Type.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/lib/AST/Type.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/lib/Sema/SemaExceptionSpec.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
> cfe/trunk/lib/Sema/TreeTransform.h
> cfe/trunk/test/CXX/except/except.spec/p1.cpp
> cfe/trunk/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
> cfe/trunk/test/SemaTemplate/instantiate-exception-spec.cpp
>
> ...
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=217995&r1=217994&r2=217995&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Wed Sep 17 18:57:05 2014
> @@ -1623,9 +1623,9 @@ FunctionProtoType::FunctionProtoType(Qua
> QualType *exnSlot = argSlot + NumParams;
> unsigned I = 0;
> for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
> - if (ExceptionType->isDependentType())
> - setDependent();
> - else if (ExceptionType->isInstantiationDependentType())
> + // Note that a dependent exception specification does *not* make
> + // a type dependent; it's not even part of the C++ type system.
> + if (ExceptionType->isInstantiationDependentType())
> setInstantiationDependent();
>
> if (ExceptionType->containsUnexpandedParameterPack())
> @@ -1639,11 +1639,12 @@ FunctionProtoType::FunctionProtoType(Qua
> *noexSlot = epi.ExceptionSpec.NoexceptExpr;
>
> if (epi.ExceptionSpec.NoexceptExpr) {
> - if (epi.ExceptionSpec.NoexceptExpr->isValueDependent()
> - || epi.ExceptionSpec.NoexceptExpr->isTypeDependent())
> - setDependent();
> - else if (epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())
> + if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
> + epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent())
> setInstantiationDependent();
> +
> + if
> (epi.ExceptionSpec.NoexceptExpr->containsUnexpandedParameterPack())
> + setContainsUnexpandedParameterPack();
> }
> } else if (getExceptionSpecType() == EST_Uninstantiated) {
> // Store the function decl from which we will resolve our
> @@ -1669,6 +1670,19 @@ FunctionProtoType::FunctionProtoType(Qua
> }
> }
>
> +bool FunctionProtoType::hasDependentExceptionSpec() const {
> + if (Expr *NE = getNoexceptExpr())
> + return NE->isValueDependent();
> + for (unsigned I = 0, N = getNumExceptions(); I != N; ++I)
>
This crashes on test/CXX/except/except.spec/template.cpp in certain build
configurations. I suspect, the reason is the complicated relation between
getNumExceptions/getExceptionType and exception_begin/exception_end:
exception_iterator exception_end() const {
if (getExceptionSpecType() != EST_Dynamic)
return exception_begin();
return exception_begin() + NumExceptions;
}
...
unsigned getNumExceptions() const { return NumExceptions; }
QualType getExceptionType(unsigned i) const {
assert(i < NumExceptions && "Invalid exception number!");
return exception_begin()[i];
}
I wonder why the two ways to access exceptions are different. It looks like
a bug.
Actually, I don't think we need getNumExceptions/getExceptionType, since
there is ArrayRef<QualType> exceptions();.
> + // A pack expansion with a non-dependent pattern is still dependent,
> + // because we don't know whether the pattern is in the exception spec
> + // or not (that depends on whether the pack has 0 expansions).
> + if (getExceptionType(I)->isDependentType() ||
> + getExceptionType(I)->getAs<PackExpansionType>())
> + return true;
> + return false;
> +}
> +
> FunctionProtoType::NoexceptResult
> FunctionProtoType::getNoexceptSpec(const ASTContext &ctx) const {
> ExceptionSpecificationType est = getExceptionSpecType();
> ...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140918/f2b67368/attachment.html>
More information about the cfe-commits
mailing list