diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-28 22:52:42 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-11-28 22:52:42 +0000 |
commit | a70c3f8738cc123ded68c183cedd6e93df670c2f (patch) | |
tree | 674b48f01151ea3e22fd62ada9a564529e86a140 /lib/Sema/SemaExceptionSpec.cpp | |
parent | 21173b1080abaa2738f9e700a9d4b0d04f928930 (diff) | |
download | clang-a70c3f8738cc123ded68c183cedd6e93df670c2f.tar.gz |
Per C++11 [except.spec]p2, rvalue references are not permitted in exception specifications.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@168824 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExceptionSpec.cpp')
-rw-r--r-- | lib/Sema/SemaExceptionSpec.cpp | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index 8cb2cb4290..e72ebf86d4 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -42,50 +42,51 @@ static const FunctionProtoType *GetUnderlyingFunction(QualType T) /// \param[in,out] T The exception type. This will be decayed to a pointer type /// when the input is an array or a function type. bool Sema::CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range) { - // This check (and the similar one below) deals with issue 437, that changes - // C++ 9.2p2 this way: - // Within the class member-specification, the class is regarded as complete - // within function bodies, default arguments, exception-specifications, and - // constructor ctor-initializers (including such things in nested classes). - if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined()) - return false; - - // C++ 15.4p2: A type cv T, "array of T", or "function returning T" denoted + // C++11 [except.spec]p2: + // A type cv T, "array of T", or "function returning T" denoted // in an exception-specification is adjusted to type T, "pointer to T", or // "pointer to function returning T", respectively. - // C++ 15.4p2: A type denoted in an exception-specification shall not denote - // an incomplete type. + // + // We also apply this rule in C++98. if (T->isArrayType()) T = Context.getArrayDecayedType(T); else if (T->isFunctionType()) T = Context.getPointerType(T); - else if (RequireCompleteType(Range.getBegin(), T, - diag::err_incomplete_in_exception_spec, - /*direct*/0, Range)) - return true; - - // C++ 15.4p2: A type denoted in an exception-specification shall not denote - // an incomplete type a pointer or reference to an incomplete type, other - // than (cv) void*. - int kind; + int Kind = 0; QualType PointeeT = T; - if (const PointerType* IT = T->getAs<PointerType>()) { - PointeeT = IT->getPointeeType(); - kind = 1; - } else if (const ReferenceType* IT = T->getAs<ReferenceType>()) { - PointeeT = IT->getPointeeType(); - kind = 2; - } else - return false; + if (const PointerType *PT = T->getAs<PointerType>()) { + PointeeT = PT->getPointeeType(); + Kind = 1; - // Again as before - if (PointeeT->isRecordType() && PointeeT->getAs<RecordType>()->isBeingDefined()) - return false; + // cv void* is explicitly permitted, despite being a pointer to an + // incomplete type. + if (PointeeT->isVoidType()) + return false; + } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { + PointeeT = RT->getPointeeType(); + Kind = 2; + + if (RT->isRValueReferenceType()) { + // C++11 [except.spec]p2: + // A type denoted in an exception-specification shall not denote [...] + // an rvalue reference type. + Diag(Range.getBegin(), diag::err_rref_in_exception_spec) + << T << Range; + return true; + } + } - if (!PointeeT->isVoidType() && + // C++11 [except.spec]p2: + // A type denoted in an exception-specification shall not denote an + // incomplete type other than a class currently being defined [...]. + // A type denoted in an exception-specification shall not denote a + // pointer or reference to an incomplete type, other than (cv) void* or a + // pointer or reference to a class currently being defined. + if (!(PointeeT->isRecordType() && + PointeeT->getAs<RecordType>()->isBeingDefined()) && RequireCompleteType(Range.getBegin(), PointeeT, - diag::err_incomplete_in_exception_spec, kind, Range)) + diag::err_incomplete_in_exception_spec, Kind, Range)) return true; return false; |