diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-05-29 15:01:05 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-05-29 15:01:05 +0000 |
commit | 6a7330c20cabf1cf1cd46f5dfc183ec3a72add66 (patch) | |
tree | 17119595836e1b6daf7830a6651db88f21c70327 /lib/Sema/SemaType.cpp | |
parent | 00c4486243ac0baa77a387335541c742c4dd615a (diff) |
Disallow exception specifications on multi-level indirections.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72571 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 83f9b60fd7..01b8aa4fd4 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -682,14 +682,35 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, .getQualifiedType(DeclType.Cls.TypeQuals)); break; case DeclaratorChunk::Pointer: + // Verify that we're not building a pointer to pointer to function with + // exception specification. + if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { + Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + D.setInvalidType(true); + // Build the type anyway. + } T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name); break; case DeclaratorChunk::Reference: + // Verify that we're not building a reference to pointer to function with + // exception specification. + if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { + Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + D.setInvalidType(true); + // Build the type anyway. + } T = BuildReferenceType(T, DeclType.Ref.LValueRef, DeclType.Ref.HasRestrict ? QualType::Restrict : 0, DeclType.Loc, Name); break; case DeclaratorChunk::Array: { + // Verify that we're not building an array of pointers to function with + // exception specification. + if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { + Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + D.setInvalidType(true); + // Build the type anyway. + } DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; Expr *ArraySize = static_cast<Expr*>(ATI.NumElts); ArrayType::ArraySizeModifier ASM; @@ -834,6 +855,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, break; } case DeclaratorChunk::MemberPointer: + // Verify that we're not building a pointer to pointer to function with + // exception specification. + if (getLangOptions().CPlusPlus && CheckDistantExceptionSpec(T)) { + Diag(D.getIdentifierLoc(), diag::err_distant_exception_spec); + D.setInvalidType(true); + // Build the type anyway. + } // The scope spec must refer to a class, or be dependent. DeclContext *DC = computeDeclContext(DeclType.Mem.Scope()); QualType ClsType; @@ -925,6 +953,24 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip, return T; } +/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer +/// to member to a function with an exception specification. This means that +/// it is invalid to add another level of indirection. +bool Sema::CheckDistantExceptionSpec(QualType T) { + if (const PointerType *PT = T->getAsPointerType()) + T = PT->getPointeeType(); + else if (const MemberPointerType *PT = T->getAsMemberPointerType()) + T = PT->getPointeeType(); + else + return false; + + const FunctionProtoType *FnT = T->getAsFunctionProtoType(); + if (!FnT) + return false; + + return FnT->hasExceptionSpec(); +} + /// ObjCGetTypeForMethodDefinition - Builds the type for a method definition /// declarator QualType Sema::ObjCGetTypeForMethodDefinition(DeclPtrTy D) { |