forked from OSchip/llvm-project
Per C++11 [except.spec]p2, rvalue references are not permitted in exception specifications.
llvm-svn: 168824
This commit is contained in:
parent
8606d75265
commit
a118c6a8c0
|
@ -892,6 +892,8 @@ def err_distant_exception_spec : Error<
|
||||||
def err_incomplete_in_exception_spec : Error<
|
def err_incomplete_in_exception_spec : Error<
|
||||||
"%select{|pointer to |reference to }0incomplete type %1 is not allowed "
|
"%select{|pointer to |reference to }0incomplete type %1 is not allowed "
|
||||||
"in exception specification">;
|
"in exception specification">;
|
||||||
|
def err_rref_in_exception_spec : Error<
|
||||||
|
"rvalue reference type %0 is not allowed in exception specification">;
|
||||||
def err_mismatched_exception_spec : Error<
|
def err_mismatched_exception_spec : Error<
|
||||||
"exception specification in declaration does not match previous declaration">;
|
"exception specification in declaration does not match previous declaration">;
|
||||||
def warn_mismatched_exception_spec : ExtWarn<
|
def warn_mismatched_exception_spec : ExtWarn<
|
||||||
|
|
|
@ -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
|
/// \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.
|
/// when the input is an array or a function type.
|
||||||
bool Sema::CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range) {
|
bool Sema::CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range) {
|
||||||
// This check (and the similar one below) deals with issue 437, that changes
|
// C++11 [except.spec]p2:
|
||||||
// C++ 9.2p2 this way:
|
// A type cv T, "array of T", or "function returning T" denoted
|
||||||
// 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
|
|
||||||
// in an exception-specification is adjusted to type T, "pointer to T", or
|
// in an exception-specification is adjusted to type T, "pointer to T", or
|
||||||
// "pointer to function returning T", respectively.
|
// "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())
|
if (T->isArrayType())
|
||||||
T = Context.getArrayDecayedType(T);
|
T = Context.getArrayDecayedType(T);
|
||||||
else if (T->isFunctionType())
|
else if (T->isFunctionType())
|
||||||
T = Context.getPointerType(T);
|
T = Context.getPointerType(T);
|
||||||
else if (RequireCompleteType(Range.getBegin(), T,
|
|
||||||
diag::err_incomplete_in_exception_spec,
|
|
||||||
/*direct*/0, Range))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
int Kind = 0;
|
||||||
// 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;
|
|
||||||
QualType PointeeT = T;
|
QualType PointeeT = T;
|
||||||
if (const PointerType* IT = T->getAs<PointerType>()) {
|
if (const PointerType *PT = T->getAs<PointerType>()) {
|
||||||
PointeeT = IT->getPointeeType();
|
PointeeT = PT->getPointeeType();
|
||||||
kind = 1;
|
Kind = 1;
|
||||||
} else if (const ReferenceType* IT = T->getAs<ReferenceType>()) {
|
|
||||||
PointeeT = IT->getPointeeType();
|
|
||||||
kind = 2;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Again as before
|
// cv void* is explicitly permitted, despite being a pointer to an
|
||||||
if (PointeeT->isRecordType() && PointeeT->getAs<RecordType>()->isBeingDefined())
|
// incomplete type.
|
||||||
return false;
|
if (PointeeT->isVoidType())
|
||||||
|
return false;
|
||||||
|
} else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
|
||||||
|
PointeeT = RT->getPointeeType();
|
||||||
|
Kind = 2;
|
||||||
|
|
||||||
if (!PointeeT->isVoidType() &&
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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,
|
RequireCompleteType(Range.getBegin(), PointeeT,
|
||||||
diag::err_incomplete_in_exception_spec, kind, Range))
|
diag::err_incomplete_in_exception_spec, Kind, Range))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -143,3 +143,5 @@ namespace Decay {
|
||||||
struct E; // expected-note {{forward declaration}}
|
struct E; // expected-note {{forward declaration}}
|
||||||
C<E[10]> e; // expected-note {{in instantiation of}}
|
C<E[10]> e; // expected-note {{in instantiation of}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} expected-warning {{C++11}}
|
||||||
|
|
Loading…
Reference in New Issue