diff options
-rw-r--r-- | clang/include/clang/AST/Stmt.h | 12 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 2 | ||||
-rw-r--r-- | clang/test/PCH/stmt-attrs.cpp | 23 |
4 files changed, 35 insertions, 9 deletions
diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 10afca4fbd1..88cbb21b811 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -819,21 +819,25 @@ class AttributedStmt : public Stmt { Stmt *SubStmt; SourceLocation AttrLoc; unsigned NumAttrs; - const Attr *Attrs[1]; friend class ASTStmtReader; AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt) : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc), NumAttrs(Attrs.size()) { - memcpy(this->Attrs, Attrs.data(), Attrs.size() * sizeof(Attr*)); + memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *)); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) { - memset(Attrs, 0, NumAttrs * sizeof(Attr*)); + memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *)); } + Attr *const *getAttrArrayPtr() const { + return reinterpret_cast<Attr *const *>(this + 1); + } + Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); } + public: static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt); @@ -842,7 +846,7 @@ public: SourceLocation getAttrLoc() const { return AttrLoc; } ArrayRef<const Attr*> getAttrs() const { - return ArrayRef<const Attr*>(Attrs, NumAttrs); + return ArrayRef<const Attr*>(getAttrArrayPtr(), NumAttrs); } Stmt *getSubStmt() { return SubStmt; } const Stmt *getSubStmt() const { return SubStmt; } diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index e6468f760a5..8588dda363c 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -285,8 +285,8 @@ const char *LabelStmt::getName() const { AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt) { - void *Mem = C.Allocate(sizeof(AttributedStmt) + - sizeof(Attr*) * (Attrs.size() - 1), + assert(!Attrs.empty() && "Attrs should not be empty"); + void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * Attrs.size(), llvm::alignOf<AttributedStmt>()); return new (Mem) AttributedStmt(Loc, Attrs, SubStmt); } @@ -294,8 +294,7 @@ AttributedStmt *AttributedStmt::Create(const ASTContext &C, SourceLocation Loc, AttributedStmt *AttributedStmt::CreateEmpty(const ASTContext &C, unsigned NumAttrs) { assert(NumAttrs > 0 && "NumAttrs should be greater than zero"); - void *Mem = C.Allocate(sizeof(AttributedStmt) + - sizeof(Attr*) * (NumAttrs - 1), + void *Mem = C.Allocate(sizeof(AttributedStmt) + sizeof(Attr *) * NumAttrs, llvm::alignOf<AttributedStmt>()); return new (Mem) AttributedStmt(EmptyShell(), NumAttrs); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index ce44fea84a1..3501817916e 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -176,7 +176,7 @@ void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) { (void)NumAttrs; assert(NumAttrs == S->NumAttrs); assert(NumAttrs == Attrs.size()); - std::copy(Attrs.begin(), Attrs.end(), S->Attrs); + std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr()); S->SubStmt = Reader.ReadSubStmt(); S->AttrLoc = ReadSourceLocation(Record, Idx); } diff --git a/clang/test/PCH/stmt-attrs.cpp b/clang/test/PCH/stmt-attrs.cpp new file mode 100644 index 00000000000..9cf66427096 --- /dev/null +++ b/clang/test/PCH/stmt-attrs.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -emit-pch -o %t.a %s
+// RUN: %clang_cc1 -std=c++11 -include-pch %t.a %s -ast-print -o - | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+inline void test(int i) {
+ switch (i) {
+ case 1:
+ // Notice that the NullStmt has two attributes.
+ [[clang::fallthrough]][[clang::fallthrough]];
+ case 2:
+ break;
+ }
+}
+
+#else
+
+void foo(void) {
+ test(1);
+}
+
+#endif
|