Fix for Bug 18536 - Bad alignment in clang/AST/StmpOpenMP.h

llvm-svn: 202141
This commit is contained in:
Alexey Bataev 2014-02-25 11:25:38 +00:00
parent 25adb7b00c
commit 1319381686
3 changed files with 83 additions and 63 deletions

View File

@ -67,7 +67,7 @@ public:
/// \brief This represents clauses with the list of variables like 'private', /// \brief This represents clauses with the list of variables like 'private',
/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
/// '#pragma omp ...' directives. /// '#pragma omp ...' directives.
template <class T> class OMPVarList { template <class T> class OMPVarListClause : public OMPClause {
friend class OMPClauseReader; friend class OMPClauseReader;
/// \brief Location of '('. /// \brief Location of '('.
SourceLocation LParenLoc; SourceLocation LParenLoc;
@ -78,23 +78,34 @@ protected:
/// \brief Fetches list of variables associated with this clause. /// \brief Fetches list of variables associated with this clause.
llvm::MutableArrayRef<Expr *> getVarRefs() { llvm::MutableArrayRef<Expr *> getVarRefs() {
return llvm::MutableArrayRef<Expr *>( return llvm::MutableArrayRef<Expr *>(
reinterpret_cast<Expr **>(static_cast<T *>(this) + 1), NumVars); reinterpret_cast<Expr **>(
reinterpret_cast<char *>(this) +
llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
NumVars);
} }
/// \brief Sets the list of variables for this clause. /// \brief Sets the list of variables for this clause.
void setVarRefs(ArrayRef<Expr *> VL) { void setVarRefs(ArrayRef<Expr *> VL) {
assert(VL.size() == NumVars && assert(VL.size() == NumVars &&
"Number of variables is not the same as the preallocated buffer"); "Number of variables is not the same as the preallocated buffer");
std::copy(VL.begin(), VL.end(), std::copy(
reinterpret_cast<Expr **>(static_cast<T *>(this) + 1)); VL.begin(), VL.end(),
reinterpret_cast<Expr **>(
reinterpret_cast<char *>(this) +
llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
} }
/// \brief Build clause with number of variables \a N. /// \brief Build clause with number of variables \a N.
/// ///
/// \param K Kind of the clause.
/// \param StartLoc Starting location of the clause (the clause keyword).
/// \param LParenLoc Location of '('.
/// \param EndLoc Ending location of the clause.
/// \param N Number of the variables in the clause. /// \param N Number of the variables in the clause.
/// ///
OMPVarList(SourceLocation LParenLoc, unsigned N) OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
: LParenLoc(LParenLoc), NumVars(N) {} SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
: OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
public: public:
typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator; typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
@ -115,7 +126,9 @@ public:
/// \brief Fetches list of all variables in the clause. /// \brief Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const { ArrayRef<const Expr *> getVarRefs() const {
return ArrayRef<const Expr *>( return ArrayRef<const Expr *>(
reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1), reinterpret_cast<const Expr *const *>(
reinterpret_cast<const char *>(this) +
llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
NumVars); NumVars);
} }
}; };
@ -250,7 +263,7 @@ public:
/// In this example directive '#pragma omp parallel' has clause 'private' /// In this example directive '#pragma omp parallel' has clause 'private'
/// with the variables 'a' and 'b'. /// with the variables 'a' and 'b'.
/// ///
class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> { class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
/// \brief Build clause with number of variables \a N. /// \brief Build clause with number of variables \a N.
/// ///
/// \param StartLoc Starting location of the clause. /// \param StartLoc Starting location of the clause.
@ -260,16 +273,17 @@ class OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> {
/// ///
OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N) SourceLocation EndLoc, unsigned N)
: OMPClause(OMPC_private, StartLoc, EndLoc), : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
OMPVarList<OMPPrivateClause>(LParenLoc, N) {} EndLoc, N) {}
/// \brief Build an empty clause. /// \brief Build an empty clause.
/// ///
/// \param N Number of variables. /// \param N Number of variables.
/// ///
explicit OMPPrivateClause(unsigned N) explicit OMPPrivateClause(unsigned N)
: OMPClause(OMPC_private, SourceLocation(), SourceLocation()), : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
OMPVarList<OMPPrivateClause>(SourceLocation(), N) {} SourceLocation(), SourceLocation(),
N) {}
public: public:
/// \brief Creates clause with a list of variables \a VL. /// \brief Creates clause with a list of variables \a VL.
@ -309,8 +323,7 @@ public:
/// In this example directive '#pragma omp parallel' has clause 'firstprivate' /// In this example directive '#pragma omp parallel' has clause 'firstprivate'
/// with the variables 'a' and 'b'. /// with the variables 'a' and 'b'.
/// ///
class OMPFirstprivateClause : public OMPClause, class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
public OMPVarList<OMPFirstprivateClause> {
/// \brief Build clause with number of variables \a N. /// \brief Build clause with number of variables \a N.
/// ///
/// \param StartLoc Starting location of the clause. /// \param StartLoc Starting location of the clause.
@ -320,16 +333,17 @@ class OMPFirstprivateClause : public OMPClause,
/// ///
OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N) SourceLocation EndLoc, unsigned N)
: OMPClause(OMPC_firstprivate, StartLoc, EndLoc), : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
OMPVarList<OMPFirstprivateClause>(LParenLoc, N) {} LParenLoc, EndLoc, N) {}
/// \brief Build an empty clause. /// \brief Build an empty clause.
/// ///
/// \param N Number of variables. /// \param N Number of variables.
/// ///
explicit OMPFirstprivateClause(unsigned N) explicit OMPFirstprivateClause(unsigned N)
: OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()), : OMPVarListClause<OMPFirstprivateClause>(
OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) {} OMPC_firstprivate, SourceLocation(), SourceLocation(),
SourceLocation(), N) {}
public: public:
/// \brief Creates clause with a list of variables \a VL. /// \brief Creates clause with a list of variables \a VL.
@ -368,7 +382,7 @@ public:
/// In this example directive '#pragma omp parallel' has clause 'shared' /// In this example directive '#pragma omp parallel' has clause 'shared'
/// with the variables 'a' and 'b'. /// with the variables 'a' and 'b'.
/// ///
class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> { class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
/// \brief Build clause with number of variables \a N. /// \brief Build clause with number of variables \a N.
/// ///
/// \param StartLoc Starting location of the clause. /// \param StartLoc Starting location of the clause.
@ -378,16 +392,17 @@ class OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> {
/// ///
OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, unsigned N) SourceLocation EndLoc, unsigned N)
: OMPClause(OMPC_shared, StartLoc, EndLoc), : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
OMPVarList<OMPSharedClause>(LParenLoc, N) {} EndLoc, N) {}
/// \brief Build an empty clause. /// \brief Build an empty clause.
/// ///
/// \param N Number of variables. /// \param N Number of variables.
/// ///
explicit OMPSharedClause(unsigned N) explicit OMPSharedClause(unsigned N)
: OMPClause(OMPC_shared, SourceLocation(), SourceLocation()), : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
OMPVarList<OMPSharedClause>(SourceLocation(), N) {} SourceLocation(), SourceLocation(),
N) {}
public: public:
/// \brief Creates clause with a list of variables \a VL. /// \brief Creates clause with a list of variables \a VL.

View File

@ -42,6 +42,7 @@ class OMPExecutableDirective : public Stmt {
llvm::MutableArrayRef<OMPClause *> Clauses; llvm::MutableArrayRef<OMPClause *> Clauses;
/// \brief Associated statement (if any) and expressions. /// \brief Associated statement (if any) and expressions.
llvm::MutableArrayRef<Stmt *> StmtAndExpressions; llvm::MutableArrayRef<Stmt *> StmtAndExpressions;
protected: protected:
/// \brief Build instance of directive of class \a K. /// \brief Build instance of directive of class \a K.
/// ///
@ -54,11 +55,14 @@ protected:
OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned NumClauses, unsigned NumberOfExpressions) unsigned NumClauses, unsigned NumberOfExpressions)
: Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc), : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1), Clauses(reinterpret_cast<OMPClause **>(
NumClauses), reinterpret_cast<char *>(this) +
StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()), llvm::RoundUpToAlignment(sizeof(T),
NumberOfExpressions) { } llvm::alignOf<OMPClause *>())),
NumClauses),
StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()),
NumberOfExpressions) {}
/// \brief Sets the list of variables for this clause. /// \brief Sets the list of variables for this clause.
/// ///
@ -70,9 +74,7 @@ protected:
/// ///
/// /param S Associated statement. /// /param S Associated statement.
/// ///
void setAssociatedStmt(Stmt *S) { void setAssociatedStmt(Stmt *S) { StmtAndExpressions[0] = S; }
StmtAndExpressions[0] = S;
}
public: public:
/// \brief Returns starting location of directive kind. /// \brief Returns starting location of directive kind.
@ -104,9 +106,7 @@ public:
} }
/// \brief Returns statement associated with the directive. /// \brief Returns statement associated with the directive.
Stmt *getAssociatedStmt() const { Stmt *getAssociatedStmt() const { return StmtAndExpressions[0]; }
return StmtAndExpressions[0];
}
OpenMPDirectiveKind getDirectiveKind() const { return Kind; } OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
@ -141,16 +141,17 @@ class OMPParallelDirective : public OMPExecutableDirective {
/// ///
OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
unsigned N) unsigned N)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
StartLoc, EndLoc, N, 1) { } StartLoc, EndLoc, N, 1) {}
/// \brief Build an empty directive. /// \brief Build an empty directive.
/// ///
/// \param N Number of clauses. /// \param N Number of clauses.
/// ///
explicit OMPParallelDirective(unsigned N) explicit OMPParallelDirective(unsigned N)
: OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
SourceLocation(), SourceLocation(), N, 1) { } SourceLocation(), SourceLocation(), N, 1) {}
public: public:
/// \brief Creates directive with a list of \a Clauses. /// \brief Creates directive with a list of \a Clauses.
/// ///
@ -160,11 +161,9 @@ public:
/// \param Clauses List of clauses. /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement associated with the directive. /// \param AssociatedStmt Statement associated with the directive.
/// ///
static OMPParallelDirective *Create(const ASTContext &C, static OMPParallelDirective *
SourceLocation StartLoc, Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt);
/// \brief Creates an empty directive with the place for \a N clauses. /// \brief Creates an empty directive with the place for \a N clauses.
/// ///
@ -179,6 +178,6 @@ public:
} }
}; };
} // end namespace clang } // end namespace clang
#endif #endif

View File

@ -1130,8 +1130,9 @@ OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C,
SourceLocation LParenLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL) { ArrayRef<Expr *> VL) {
void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * VL.size(), void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
llvm::alignOf<OMPPrivateClause>()); llvm::alignOf<Expr *>()) +
sizeof(Expr *) * VL.size());
OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc, OMPPrivateClause *Clause = new (Mem) OMPPrivateClause(StartLoc, LParenLoc,
EndLoc, VL.size()); EndLoc, VL.size());
Clause->setVarRefs(VL); Clause->setVarRefs(VL);
@ -1140,8 +1141,9 @@ OMPPrivateClause *OMPPrivateClause::Create(const ASTContext &C,
OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C, OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
unsigned N) { unsigned N) {
void *Mem = C.Allocate(sizeof(OMPPrivateClause) + sizeof(Expr *) * N, void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
llvm::alignOf<OMPPrivateClause>()); llvm::alignOf<Expr *>()) +
sizeof(Expr *) * N);
return new (Mem) OMPPrivateClause(N); return new (Mem) OMPPrivateClause(N);
} }
@ -1150,9 +1152,9 @@ OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C,
SourceLocation LParenLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL) { ArrayRef<Expr *> VL) {
void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
sizeof(Expr *) * VL.size(), llvm::alignOf<Expr *>()) +
llvm::alignOf<OMPFirstprivateClause>()); sizeof(Expr *) * VL.size());
OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc, OMPFirstprivateClause *Clause = new (Mem) OMPFirstprivateClause(StartLoc,
LParenLoc, LParenLoc,
EndLoc, EndLoc,
@ -1163,8 +1165,9 @@ OMPFirstprivateClause *OMPFirstprivateClause::Create(const ASTContext &C,
OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C, OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
unsigned N) { unsigned N) {
void *Mem = C.Allocate(sizeof(OMPFirstprivateClause) + sizeof(Expr *) * N, void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
llvm::alignOf<OMPFirstprivateClause>()); llvm::alignOf<Expr *>()) +
sizeof(Expr *) * N);
return new (Mem) OMPFirstprivateClause(N); return new (Mem) OMPFirstprivateClause(N);
} }
@ -1173,8 +1176,9 @@ OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
SourceLocation LParenLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL) { ArrayRef<Expr *> VL) {
void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * VL.size(), void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
llvm::alignOf<OMPSharedClause>()); llvm::alignOf<Expr *>()) +
sizeof(Expr *) * VL.size());
OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc, OMPSharedClause *Clause = new (Mem) OMPSharedClause(StartLoc, LParenLoc,
EndLoc, VL.size()); EndLoc, VL.size());
Clause->setVarRefs(VL); Clause->setVarRefs(VL);
@ -1183,8 +1187,9 @@ OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C,
unsigned N) { unsigned N) {
void *Mem = C.Allocate(sizeof(OMPSharedClause) + sizeof(Expr *) * N, void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
llvm::alignOf<OMPSharedClause>()); llvm::alignOf<Expr *>()) +
sizeof(Expr *) * N);
return new (Mem) OMPSharedClause(N); return new (Mem) OMPSharedClause(N);
} }
@ -1200,9 +1205,10 @@ OMPParallelDirective *OMPParallelDirective::Create(
SourceLocation EndLoc, SourceLocation EndLoc,
ArrayRef<OMPClause *> Clauses, ArrayRef<OMPClause *> Clauses,
Stmt *AssociatedStmt) { Stmt *AssociatedStmt) {
void *Mem = C.Allocate(sizeof(OMPParallelDirective) + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *), llvm::alignOf<OMPClause *>());
llvm::alignOf<OMPParallelDirective>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() +
sizeof(Stmt *));
OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc, OMPParallelDirective *Dir = new (Mem) OMPParallelDirective(StartLoc, EndLoc,
Clauses.size()); Clauses.size());
Dir->setClauses(Clauses); Dir->setClauses(Clauses);
@ -1213,8 +1219,8 @@ OMPParallelDirective *OMPParallelDirective::Create(
OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C, OMPParallelDirective *OMPParallelDirective::CreateEmpty(const ASTContext &C,
unsigned N, unsigned N,
EmptyShell) { EmptyShell) {
void *Mem = C.Allocate(sizeof(OMPParallelDirective) + unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPParallelDirective),
sizeof(OMPClause *) * N + sizeof(Stmt *), llvm::alignOf<OMPClause *>());
llvm::alignOf<OMPParallelDirective>()); void *Mem = C.Allocate(Size + sizeof(OMPClause *) * N + sizeof(Stmt *));
return new (Mem) OMPParallelDirective(N); return new (Mem) OMPParallelDirective(N);
} }