diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 4bc5b7a54c..0cb2b35f5a 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -434,10 +434,10 @@ public: /// a data type. unsigned getPreferredTypeAlign(const Type *T); - /// getDeclAlign - Return the alignment of the specified decl that should be - /// returned by __alignof(). Note that bitfields do not have a valid - /// alignment, so this method will assert on them. - unsigned getDeclAlign(const Decl *D); + /// getDeclAlignInBytes - Return the alignment of the specified decl + /// that should be returned by __alignof(). Note that bitfields do + /// not have a valid alignment, so this method will assert on them. + unsigned getDeclAlignInBytes(const Decl *D); /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c87b08627d..4a3f00f356 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -263,7 +263,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { /// getDeclAlign - Return a conservative estimate of the alignment of the /// specified decl. Note that bitfields do not have a valid alignment, so /// this method will assert on them. -unsigned ASTContext::getDeclAlign(const Decl *D) { +unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { // FIXME: If attribute(align) is specified on the decl, round up to it. if (const ValueDecl *VD = dyn_cast(D)) { @@ -275,7 +275,7 @@ unsigned ASTContext::getDeclAlign(const Decl *D) { while (isa(T) || isa(T)) T = cast(T)->getElementType(); - return getTypeAlign(T); + return getTypeAlign(T) / Target.getCharWidth(); } return 1; diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 7b3e64908a..ad83e372b4 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -981,10 +981,10 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) { // alignof decl is always accepted, even if it doesn't make sense: we default // to 1 in those cases. if (const DeclRefExpr *DRE = dyn_cast(E)) - return Info.Ctx.getDeclAlign(DRE->getDecl()); + return Info.Ctx.getDeclAlignInBytes(DRE->getDecl()); if (const MemberExpr *ME = dyn_cast(E)) - return Info.Ctx.getDeclAlign(ME->getMemberDecl()); + return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl()); return GetAlignOfType(E->getType()); } diff --git a/test/CodeGen/alignof.c b/test/CodeGen/alignof.c new file mode 100644 index 0000000000..edeb0db771 --- /dev/null +++ b/test/CodeGen/alignof.c @@ -0,0 +1,12 @@ +// RUN: clang -triple i386-unknown-unknown -O1 -emit-llvm -o %t %s && +// RUN: grep 'ret i32 4' %t + +enum e0 { E0 }; +struct s0 { + enum e0 a:31; +}; + +struct s0 t1_tmp; +int f0() { + return __alignof__(t1_tmp); +}