[cfe-commits] r47202 - in /cfe/trunk: AST/ASTContext.cpp AST/Expr.cpp include/clang/AST/Decl.h test/Sema/struct-packed-align.c
Anders Carlsson
andersca at mac.com
Fri Feb 15 17:20:23 PST 2008
Author: andersca
Date: Fri Feb 15 19:20:23 2008
New Revision: 47202
URL: http://llvm.org/viewvc/llvm-project?rev=47202&view=rev
Log:
Make sizeof and __alignof work correctly with packed structs.
Added:
cfe/trunk/test/Sema/struct-packed-align.c
Modified:
cfe/trunk/AST/ASTContext.cpp
cfe/trunk/AST/Expr.cpp
cfe/trunk/include/clang/AST/Decl.h
Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=47202&r1=47201&r2=47202&view=diff
==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Fri Feb 15 19:20:23 2008
@@ -319,10 +319,13 @@
unsigned RecordAlign = 8; // Default alignment = 1 byte = 8 bits.
if (D->getKind() != Decl::Union) {
+ bool StructIsPacked = D->getAttr<PackedAttr>();
+
// Layout each field, for now, just sequentially, respecting alignment. In
// the future, this will need to be tweakable by targets.
for (unsigned i = 0, e = D->getNumMembers(); i != e; ++i) {
const FieldDecl *FD = D->getMember(i);
+ bool FieldIsPacked = StructIsPacked || FD->getAttr<PackedAttr>();
uint64_t FieldSize;
unsigned FieldAlign;
if (FD->getType()->isIncompleteType()) {
@@ -331,12 +334,12 @@
// Flexible array members don't have any size, but they
// have to be aligned appropriately for their element type.
const ArrayType* ATy = FD->getType()->getAsArrayType();
- FieldAlign = getTypeAlign(ATy->getElementType(), L);
+ FieldAlign = FieldIsPacked ? 8 : getTypeAlign(ATy->getElementType(), L);
FieldSize = 0;
} else {
std::pair<uint64_t, unsigned> FieldInfo = getTypeInfo(FD->getType(), L);
FieldSize = FieldInfo.first;
- FieldAlign = FieldInfo.second;
+ FieldAlign = FieldIsPacked ? 8 : FieldInfo.second;
}
// Round up the current record size to the field's alignment boundary.
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=47202&r1=47201&r2=47202&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Fri Feb 15 19:20:23 2008
@@ -784,16 +784,18 @@
if (Exp->getArgumentType()->isFunctionType()) {
// GCC extension: sizeof(function) = 1.
Result = Exp->isSizeOf() ? 1 : 4;
- } else if (Exp->isSizeOf()) {
+ } else {
unsigned CharSize =
Ctx.Target.getCharWidth(Ctx.getFullLoc(Exp->getOperatorLoc()));
- Result = Ctx.getTypeSize(Exp->getArgumentType(),
- Exp->getOperatorLoc()) / CharSize;
+ if (Exp->isSizeOf())
+ Result = Ctx.getTypeSize(Exp->getArgumentType(),
+ Exp->getOperatorLoc()) / CharSize;
+ else
+ Result = Ctx.getTypeAlign(Exp->getArgumentType(),
+ Exp->getOperatorLoc()) / CharSize;
}
- else
- Result = Ctx.getTypeAlign(Exp->getArgumentType(), Exp->getOperatorLoc());
-
+
break;
}
case BinaryOperatorClass: {
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=47202&r1=47201&r2=47202&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Feb 15 19:20:23 2008
@@ -138,9 +138,9 @@
void addAttr(Attr *attr);
const Attr *getAttrs() const;
- template<typename T> T *getAttr() {
- for (Attr *attr = getAttrs(); attr; attr = attr->getNext())
- if (T *V = dyn_cast<T>(attr))
+ template<typename T> const T *getAttr() const {
+ for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
+ if (const T *V = dyn_cast<T>(attr))
return V;
return 0;
Added: cfe/trunk/test/Sema/struct-packed-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-packed-align.c?rev=47202&view=auto
==============================================================================
--- cfe/trunk/test/Sema/struct-packed-align.c (added)
+++ cfe/trunk/test/Sema/struct-packed-align.c Fri Feb 15 19:20:23 2008
@@ -0,0 +1,37 @@
+// RUN: clang %s -fsyntax-only -verify
+
+struct s {
+ char a;
+ int b __attribute__((packed));
+ char c;
+ int d;
+};
+
+struct __attribute__((packed)) packed_s {
+ char a;
+ int b __attribute__((packed));
+ char c;
+ int d;
+};
+
+struct fas {
+ char a;
+ int b[];
+};
+
+struct __attribute__((packed)) packed_fas {
+ char a;
+ int b[];
+};
+
+extern int a1[sizeof(struct s) == 12 ? 1 : -1];
+extern int a2[__alignof(struct s) == 4 ? 1 : -1];
+
+extern int b1[sizeof(struct packed_s) == 10 ? 1 : -1];
+extern int b2[__alignof(struct packed_s) == 1 ? 1 : -1];
+
+extern int c1[sizeof(struct fas) == 4 ? 1 : -1];
+extern int c2[__alignof(struct fas) == 4 ? 1 : -1];
+
+extern int d1[sizeof(struct packed_fas) == 1 ? 1 : -1];
+extern int d2[__alignof(struct packed_fas) == 1 ? 1 : -1];
More information about the cfe-commits
mailing list