зеркало из https://github.com/microsoft/clang-1.git
Disallow exception specs on typedefs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72664 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bb6415c69f
Коммит
3cc9726a49
|
@ -269,12 +269,14 @@ def err_deleted_decl_not_first : Error<
|
|||
"deleted definition must be first declaration">;
|
||||
|
||||
// C++ exception specifications
|
||||
def err_exception_spec_in_typedef : Error<
|
||||
"exception specifications are not allowed in typedefs">;
|
||||
def err_distant_exception_spec : Error<
|
||||
"exception specifications are not allowed beyond a single level "
|
||||
"of indirection">;
|
||||
def err_incomplete_in_exception_spec : Error<
|
||||
"%select{|pointer to |member pointer to |reference to }1incomplete type %0 "
|
||||
"is not allowed in exception specification">;
|
||||
"%select{|pointer to |reference to }1incomplete type %0 is not allowed "
|
||||
"in exception specification">;
|
||||
|
||||
// C++ access checking
|
||||
def err_class_redeclared_with_different_access : Error<
|
||||
|
|
|
@ -559,6 +559,10 @@ struct DeclaratorChunk {
|
|||
/// the function has one.
|
||||
unsigned NumExceptions;
|
||||
|
||||
/// ThrowLoc - When hasExceptionSpec is true, the location of the throw
|
||||
/// keyword introducing the spec.
|
||||
unsigned ThrowLoc;
|
||||
|
||||
/// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that
|
||||
/// describe the arguments for this function declarator. This is null if
|
||||
/// there are no arguments specified.
|
||||
|
@ -588,6 +592,9 @@ struct DeclaratorChunk {
|
|||
SourceLocation getEllipsisLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(EllipsisLoc);
|
||||
}
|
||||
SourceLocation getThrowLoc() const {
|
||||
return SourceLocation::getFromRawEncoding(ThrowLoc);
|
||||
}
|
||||
};
|
||||
|
||||
struct BlockPointerTypeInfo {
|
||||
|
@ -704,6 +711,7 @@ struct DeclaratorChunk {
|
|||
SourceLocation EllipsisLoc,
|
||||
ParamInfo *ArgInfo, unsigned NumArgs,
|
||||
unsigned TypeQuals, bool hasExceptionSpec,
|
||||
SourceLocation ThrowLoc,
|
||||
bool hasAnyExceptionSpec,
|
||||
ActionBase::TypeTy **Exceptions,
|
||||
SourceRange *ExceptionRanges,
|
||||
|
|
|
@ -33,6 +33,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
|||
unsigned NumArgs,
|
||||
unsigned TypeQuals,
|
||||
bool hasExceptionSpec,
|
||||
SourceLocation ThrowLoc,
|
||||
bool hasAnyExceptionSpec,
|
||||
ActionBase::TypeTy **Exceptions,
|
||||
SourceRange *ExceptionRanges,
|
||||
|
@ -50,6 +51,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
|||
I.Fun.NumArgs = NumArgs;
|
||||
I.Fun.ArgInfo = 0;
|
||||
I.Fun.hasExceptionSpec = hasExceptionSpec;
|
||||
I.Fun.ThrowLoc = ThrowLoc.getRawEncoding();
|
||||
I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec;
|
||||
I.Fun.NumExceptions = NumExceptions;
|
||||
I.Fun.Exceptions = 0;
|
||||
|
|
|
@ -2274,6 +2274,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
// cv-qualifier-seq[opt].
|
||||
DeclSpec DS;
|
||||
bool hasExceptionSpec = false;
|
||||
SourceLocation ThrowLoc;
|
||||
bool hasAnyExceptionSpec = false;
|
||||
llvm::SmallVector<TypeTy*, 2> Exceptions;
|
||||
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
||||
|
@ -2285,6 +2286,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
// Parse exception-specification[opt].
|
||||
if (Tok.is(tok::kw_throw)) {
|
||||
hasExceptionSpec = true;
|
||||
ThrowLoc = Tok.getLocation();
|
||||
ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges,
|
||||
hasAnyExceptionSpec);
|
||||
assert(Exceptions.size() == ExceptionRanges.size() &&
|
||||
|
@ -2299,7 +2301,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
SourceLocation(),
|
||||
/*arglist*/ 0, 0,
|
||||
DS.getTypeQualifiers(),
|
||||
hasExceptionSpec,
|
||||
hasExceptionSpec, ThrowLoc,
|
||||
hasAnyExceptionSpec,
|
||||
Exceptions.data(),
|
||||
ExceptionRanges.data(),
|
||||
|
@ -2448,6 +2450,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
|
||||
DeclSpec DS;
|
||||
bool hasExceptionSpec = false;
|
||||
SourceLocation ThrowLoc;
|
||||
bool hasAnyExceptionSpec = false;
|
||||
llvm::SmallVector<TypeTy*, 2> Exceptions;
|
||||
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
||||
|
@ -2460,6 +2463,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
// Parse exception-specification[opt].
|
||||
if (Tok.is(tok::kw_throw)) {
|
||||
hasExceptionSpec = true;
|
||||
ThrowLoc = Tok.getLocation();
|
||||
ParseExceptionSpecification(Loc, Exceptions, ExceptionRanges,
|
||||
hasAnyExceptionSpec);
|
||||
assert(Exceptions.size() == ExceptionRanges.size() &&
|
||||
|
@ -2472,7 +2476,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
|||
EllipsisLoc,
|
||||
ParamInfo.data(), ParamInfo.size(),
|
||||
DS.getTypeQualifiers(),
|
||||
hasExceptionSpec,
|
||||
hasExceptionSpec, ThrowLoc,
|
||||
hasAnyExceptionSpec,
|
||||
Exceptions.data(),
|
||||
ExceptionRanges.data(),
|
||||
|
@ -2551,7 +2555,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
|||
SourceLocation(),
|
||||
&ParamInfo[0], ParamInfo.size(),
|
||||
/*TypeQuals*/0,
|
||||
/*exception*/false, false, 0, 0, 0,
|
||||
/*exception*/false,
|
||||
SourceLocation(), false, 0, 0, 0,
|
||||
LParenLoc, D),
|
||||
RLoc);
|
||||
}
|
||||
|
|
|
@ -1481,7 +1481,8 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
|||
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
|
||||
SourceLocation(),
|
||||
0, 0, 0,
|
||||
false, false, 0, 0, 0,
|
||||
false, SourceLocation(),
|
||||
false, 0, 0, 0,
|
||||
CaretLoc, ParamInfo),
|
||||
CaretLoc);
|
||||
|
||||
|
|
|
@ -3164,7 +3164,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
|||
assert(!Error && "Error setting up implicit decl!");
|
||||
Declarator D(DS, Declarator::BlockContext);
|
||||
D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
|
||||
0, 0, false, false, 0,0,0, Loc, D),
|
||||
0, 0, false, SourceLocation(),
|
||||
false, 0,0,0, Loc, D),
|
||||
SourceLocation());
|
||||
D.SetIdentifier(&II, Loc);
|
||||
|
||||
|
|
|
@ -737,7 +737,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
|
|||
// does not have a K&R-style identifier list), then the arguments are part
|
||||
// of the type, otherwise the argument list is ().
|
||||
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
|
||||
|
||||
|
||||
// C99 6.7.5.3p1: The return type may not be a function or array type.
|
||||
if (T->isArrayType() || T->isFunctionType()) {
|
||||
Diag(DeclType.Loc, diag::err_func_returning_array_function) << T;
|
||||
|
@ -754,6 +754,12 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
|
|||
<< Context.getTypeDeclType(Tag);
|
||||
}
|
||||
|
||||
// Exception specs are not allowed in typedefs. Complain, but add it
|
||||
// anyway.
|
||||
if (FTI.hasExceptionSpec &&
|
||||
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef)
|
||||
Diag(FTI.getThrowLoc(), diag::err_exception_spec_in_typedef);
|
||||
|
||||
if (FTI.NumArgs == 0) {
|
||||
if (getLangOptions().CPlusPlus) {
|
||||
// C++ 8.3.5p2: If the parameter-declaration-clause is empty, the
|
||||
|
@ -978,17 +984,13 @@ bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) {
|
|||
// 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*.
|
||||
// The standard does not mention member pointers, but it has to mean them too.
|
||||
int kind;
|
||||
if (const PointerType* IT = T->getAsPointerType()) {
|
||||
T = IT->getPointeeType();
|
||||
kind = 1;
|
||||
} else if (const MemberPointerType* IT = T->getAsMemberPointerType()) {
|
||||
T = IT->getPointeeType();
|
||||
kind = 2;
|
||||
} else if (const ReferenceType* IT = T->getAsReferenceType()) {
|
||||
T = IT->getPointeeType();
|
||||
kind = 3;
|
||||
kind = 2;
|
||||
} else
|
||||
return false;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ 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
|
||||
typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}}
|
||||
|
||||
// Some more:
|
||||
// Function returning function with spec
|
||||
|
|
Загрузка…
Ссылка в новой задаче