[cfe-commits] r72571 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaType.cpp test/SemaCXX/exception-spec.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Fri May 29 08:01:17 PDT 2009
Author: cornedbee
Date: Fri May 29 10:01:05 2009
New Revision: 72571
URL: http://llvm.org/viewvc/llvm-project?rev=72571&view=rev
Log:
Disallow exception specifications on multi-level indirections.
Added:
cfe/trunk/test/SemaCXX/exception-spec.cpp (with props)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaType.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=72571&r1=72570&r2=72571&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 29 10:01:05 2009
@@ -268,6 +268,11 @@
def err_deleted_decl_not_first : Error<
"deleted definition must be first declaration">;
+// C++ exception specifications
+def err_distant_exception_spec : Error<
+ "exception specifications are not allowed beyond a single level "
+ "of indirection">;
+
// C++ access checking
def err_class_redeclared_with_different_access : Error<
"%0 redeclared with '%1' access">;
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=72571&r1=72570&r2=72571&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May 29 10:01:05 2009
@@ -349,6 +349,7 @@
QualType GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip = 0,
TagDecl **OwnedDecl = 0);
DeclarationName GetNameForDeclarator(Declarator &D);
+ bool CheckDistantExceptionSpec(QualType T);
QualType ObjCGetTypeForMethodDefinition(DeclPtrTy D);
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=72571&r1=72570&r2=72571&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Fri May 29 10:01:05 2009
@@ -682,14 +682,35 @@
.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 @@
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 @@
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) {
Added: cfe/trunk/test/SemaCXX/exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exception-spec.cpp?rev=72571&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/exception-spec.cpp (added)
+++ cfe/trunk/test/SemaCXX/exception-spec.cpp Fri May 29 10:01:05 2009
@@ -0,0 +1,25 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// Straight from the standard:
+// Plain function with spec
+void f() throw(int);
+// Pointer to function with spec
+void (*fp)() throw (int);
+// Function taking reference to function with spec
+void g(void pfa() throw(int));
+// Typedef for pointer to function with spec
+typedef int (*pf)() throw(int); // xpected-error spec-on-typedef
+
+// Some more:
+// Function returning function with spec
+void (*h())() throw(int);
+// Ultimate parser thrill: function with spec returning function with spec and
+// taking pointer to function with spec.
+// The actual function throws int, the return type double, the argument float.
+void (*i() throw(int))(void (*)() throw(float)) throw(double);
+// Pointer to pointer to function taking function with spec
+void (**k)(void pfa() throw(int)); // no-error
+// Pointer to pointer to function with spec
+void (**j)() throw(int); // expected-error {{not allowed beyond a single}}
+// Pointer to function returning pointer to pointer to function with spec
+void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}}
Propchange: cfe/trunk/test/SemaCXX/exception-spec.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/SemaCXX/exception-spec.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/SemaCXX/exception-spec.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list