summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/Stmt.h12
-rw-r--r--clang/lib/AST/Stmt.cpp7
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--clang/test/PCH/stmt-attrs.cpp23
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
OpenPOWER on IntegriCloud