@@ -682,14 +682,35 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
682
682
.getQualifiedType (DeclType.Cls .TypeQuals ));
683
683
break ;
684
684
case DeclaratorChunk::Pointer:
685
+ // Verify that we're not building a pointer to pointer to function with
686
+ // exception specification.
687
+ if (getLangOptions ().CPlusPlus && CheckDistantExceptionSpec (T)) {
688
+ Diag (D.getIdentifierLoc (), diag::err_distant_exception_spec);
689
+ D.setInvalidType (true );
690
+ // Build the type anyway.
691
+ }
685
692
T = BuildPointerType (T, DeclType.Ptr .TypeQuals , DeclType.Loc , Name);
686
693
break ;
687
694
case DeclaratorChunk::Reference:
695
+ // Verify that we're not building a reference to pointer to function with
696
+ // exception specification.
697
+ if (getLangOptions ().CPlusPlus && CheckDistantExceptionSpec (T)) {
698
+ Diag (D.getIdentifierLoc (), diag::err_distant_exception_spec);
699
+ D.setInvalidType (true );
700
+ // Build the type anyway.
701
+ }
688
702
T = BuildReferenceType (T, DeclType.Ref .LValueRef ,
689
703
DeclType.Ref .HasRestrict ? QualType::Restrict : 0 ,
690
704
DeclType.Loc , Name);
691
705
break ;
692
706
case DeclaratorChunk::Array: {
707
+ // Verify that we're not building an array of pointers to function with
708
+ // exception specification.
709
+ if (getLangOptions ().CPlusPlus && CheckDistantExceptionSpec (T)) {
710
+ Diag (D.getIdentifierLoc (), diag::err_distant_exception_spec);
711
+ D.setInvalidType (true );
712
+ // Build the type anyway.
713
+ }
693
714
DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr ;
694
715
Expr *ArraySize = static_cast <Expr*>(ATI.NumElts );
695
716
ArrayType::ArraySizeModifier ASM;
@@ -834,6 +855,13 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
834
855
break ;
835
856
}
836
857
case DeclaratorChunk::MemberPointer:
858
+ // Verify that we're not building a pointer to pointer to function with
859
+ // exception specification.
860
+ if (getLangOptions ().CPlusPlus && CheckDistantExceptionSpec (T)) {
861
+ Diag (D.getIdentifierLoc (), diag::err_distant_exception_spec);
862
+ D.setInvalidType (true );
863
+ // Build the type anyway.
864
+ }
837
865
// The scope spec must refer to a class, or be dependent.
838
866
DeclContext *DC = computeDeclContext (DeclType.Mem .Scope ());
839
867
QualType ClsType;
@@ -925,6 +953,24 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
925
953
return T;
926
954
}
927
955
956
+ // / CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
957
+ // / to member to a function with an exception specification. This means that
958
+ // / it is invalid to add another level of indirection.
959
+ bool Sema::CheckDistantExceptionSpec (QualType T) {
960
+ if (const PointerType *PT = T->getAsPointerType ())
961
+ T = PT->getPointeeType ();
962
+ else if (const MemberPointerType *PT = T->getAsMemberPointerType ())
963
+ T = PT->getPointeeType ();
964
+ else
965
+ return false ;
966
+
967
+ const FunctionProtoType *FnT = T->getAsFunctionProtoType ();
968
+ if (!FnT)
969
+ return false ;
970
+
971
+ return FnT->hasExceptionSpec ();
972
+ }
973
+
928
974
// / ObjCGetTypeForMethodDefinition - Builds the type for a method definition
929
975
// / declarator
930
976
QualType Sema::ObjCGetTypeForMethodDefinition (DeclPtrTy D) {
0 commit comments