r217995 - Instantiate exception specifications when instantiating function types (other
Alexander Kornienko
alexfh at google.com
Thu Sep 18 08:32:24 PDT 2014
On Thu, Sep 18, 2014 at 4:32 PM, Alexander Kornienko <alexfh at google.com>
wrote:
> 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();.
>
I've changed the code to use exceptions() instead of
getNumExceptions/getExceptionType in r218053. All tests pass and the crash
in my setup disappeared, so I assume that this is the right thing to do ;)
>
>
>> + // 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/1048f18a/attachment.html>
More information about the cfe-commits
mailing list