diff --git a/clang/include/clang/AST/StmtObjC.h b/clang/include/clang/AST/StmtObjC.h --- a/clang/include/clang/AST/StmtObjC.h +++ b/clang/include/clang/AST/StmtObjC.h @@ -162,8 +162,14 @@ }; /// Represents Objective-C's \@try ... \@catch ... \@finally statement. -class ObjCAtTryStmt : public Stmt { -private: +class ObjCAtTryStmt final + : public Stmt, + private llvm::TrailingObjects { + friend TrailingObjects; + size_t numTrailingObjects(OverloadToken) const { + return 1 + NumCatchStmts + HasFinally; + } + // The location of the @ in the \@try. SourceLocation AtTryLoc; @@ -178,10 +184,8 @@ /// The order of the statements in memory follows the order in the source, /// with the \@try body first, followed by the \@catch statements (if any) /// and, finally, the \@finally (if it exists). - Stmt **getStmts() { return reinterpret_cast (this + 1); } - const Stmt* const *getStmts() const { - return reinterpret_cast (this + 1); - } + Stmt **getStmts() { return getTrailingObjects(); } + Stmt *const *getStmts() const { return getTrailingObjects(); } ObjCAtTryStmt(SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, @@ -257,8 +261,8 @@ } child_range children() { - return child_range(getStmts(), - getStmts() + 1 + NumCatchStmts + HasFinally); + return child_range( + getStmts(), getStmts() + numTrailingObjects(OverloadToken())); } const_child_range children() const { diff --git a/clang/lib/AST/StmtObjC.cpp b/clang/lib/AST/StmtObjC.cpp --- a/clang/lib/AST/StmtObjC.cpp +++ b/clang/lib/AST/StmtObjC.cpp @@ -46,9 +46,8 @@ SourceLocation atTryLoc, Stmt *atTryStmt, Stmt **CatchStmts, unsigned NumCatchStmts, Stmt *atFinallyStmt) { - unsigned Size = - sizeof(ObjCAtTryStmt) + - (1 + NumCatchStmts + (atFinallyStmt != nullptr)) * sizeof(Stmt *); + size_t Size = + totalSizeToAlloc(1 + NumCatchStmts + (atFinallyStmt != nullptr)); void *Mem = Context.Allocate(Size, alignof(ObjCAtTryStmt)); return new (Mem) ObjCAtTryStmt(atTryLoc, atTryStmt, CatchStmts, NumCatchStmts, atFinallyStmt); @@ -57,8 +56,7 @@ ObjCAtTryStmt *ObjCAtTryStmt::CreateEmpty(const ASTContext &Context, unsigned NumCatchStmts, bool HasFinally) { - unsigned Size = - sizeof(ObjCAtTryStmt) + (1 + NumCatchStmts + HasFinally) * sizeof(Stmt *); + size_t Size = totalSizeToAlloc(1 + NumCatchStmts + HasFinally); void *Mem = Context.Allocate(Size, alignof(ObjCAtTryStmt)); return new (Mem) ObjCAtTryStmt(EmptyShell(), NumCatchStmts, HasFinally); }