summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExceptionSpec.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-11-28 22:52:42 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-11-28 22:52:42 +0000
commita70c3f8738cc123ded68c183cedd6e93df670c2f (patch)
tree674b48f01151ea3e22fd62ada9a564529e86a140 /lib/Sema/SemaExceptionSpec.cpp
parent21173b1080abaa2738f9e700a9d4b0d04f928930 (diff)
downloadclang-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.cpp67
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;