From 43a5d9e409d9586db26910926b046aa8a3a69421 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 17 Feb 2009 22:16:19 +0000 Subject: [PATCH] Eek! getDeclAlign sometimes returned alignment in bits. - Renamed to getDeclAlignInBytes since most other query functions work in bits. - Fun to track down as isIntegerConstantExpr was getting it right, but Evaluate() was getting it wrong. Maybe we should assert they compute the same thing when they succeed? llvm-svn: 64828 --- clang/include/clang/AST/ASTContext.h | 8 ++++---- clang/lib/AST/ASTContext.cpp | 4 ++-- clang/lib/AST/ExprConstant.cpp | 4 ++-- clang/test/CodeGen/alignof.c | 12 ++++++++++++ 4 files changed, 20 insertions(+), 8 deletions(-) create mode 100644 clang/test/CodeGen/alignof.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 4bc5b7a54cdb..0cb2b35f5a17 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/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/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c87b08627dde..4a3f00f356aa 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/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/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 7b3e64908a4f..ad83e372b460 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/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/clang/test/CodeGen/alignof.c b/clang/test/CodeGen/alignof.c new file mode 100644 index 000000000000..edeb0db771e5 --- /dev/null +++ b/clang/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); +}