diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-11-23 17:18:46 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2009-11-23 17:18:46 +0000 |
commit | 5d484e8cf710207010720589d89602233de61d01 (patch) | |
tree | 6df800df40ae9455031556503cae9499c685c650 /lib/AST/ASTContext.cpp | |
parent | 6ec18a3f86c702004af66cce6ff979999a736898 (diff) |
Intercept sizeof and alignof references before they get into ASTContext methods. This fixes a crash when writing sizeof(Incomplete&), and lets ASTContext's methods do the right thing for CodeGen, which fixes PR5590.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89668 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index dc92afdd11..7422ca8597 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -520,7 +520,9 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { /// getDeclAlignInBytes - 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::getDeclAlignInBytes(const Decl *D) { +/// If @p RefAsPointee, references are treated like their underlying type +/// (for alignof), else they're treated like pointers (for CodeGen). +unsigned ASTContext::getDeclAlignInBytes(const Decl *D, bool RefAsPointee) { unsigned Align = Target.getCharWidth(); if (const AlignedAttr* AA = D->getAttr<AlignedAttr>()) @@ -529,9 +531,12 @@ unsigned ASTContext::getDeclAlignInBytes(const Decl *D) { if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { QualType T = VD->getType(); if (const ReferenceType* RT = T->getAs<ReferenceType>()) { - unsigned AS = RT->getPointeeType().getAddressSpace(); - Align = Target.getPointerAlign(AS); - } else if (!T->isIncompleteType() && !T->isFunctionType()) { + if (RefAsPointee) + T = RT->getPointeeType(); + else + T = getPointerType(RT->getPointeeType()); + } + if (!T->isIncompleteType() && !T->isFunctionType()) { // Incomplete or function types default to 1. while (isa<VariableArrayType>(T) || isa<IncompleteArrayType>(T)) T = cast<ArrayType>(T)->getElementType(); @@ -690,19 +695,21 @@ ASTContext::getTypeInfo(const Type *T) { Align = Target.getPointerAlign(AS); break; } + case Type::LValueReference: + case Type::RValueReference: { + // alignof and sizeof should never enter this code path here, so we go + // the pointer route. + unsigned AS = cast<ReferenceType>(T)->getPointeeType().getAddressSpace(); + Width = Target.getPointerWidth(AS); + Align = Target.getPointerAlign(AS); + break; + } case Type::Pointer: { unsigned AS = cast<PointerType>(T)->getPointeeType().getAddressSpace(); Width = Target.getPointerWidth(AS); Align = Target.getPointerAlign(AS); break; } - case Type::LValueReference: - case Type::RValueReference: - // "When applied to a reference or a reference type, the result is the size - // of the referenced type." C++98 5.3.3p2: expr.sizeof. - // FIXME: This is wrong for struct layout: a reference in a struct has - // pointer size. - return getTypeInfo(cast<ReferenceType>(T)->getPointeeType()); case Type::MemberPointer: { // FIXME: This is ABI dependent. We use the Itanium C++ ABI. // http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers |