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 | 22e2e5c423f5981527b2f4c81bf14824ac0e6a16 (patch) | |
tree | a2cd37d46285aa1abdf516bc7d9597738c58a3a8 /clang/lib/AST/ExprConstant.cpp | |
parent | a3624b6099a7d962aa181f5f149fe28ec6b63a81 (diff) | |
download | bcm5719-llvm-22e2e5c423f5981527b2f4c81bf14824ac0e6a16.tar.gz bcm5719-llvm-22e2e5c423f5981527b2f4c81bf14824ac0e6a16.zip |
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.
llvm-svn: 89668
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 2689859e8e4..d738afdd81b 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1244,6 +1244,13 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { } unsigned IntExprEvaluator::GetAlignOfType(QualType T) { + // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, + // the result is the size of the referenced type." + // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the + // result shall be the alignment of the referenced type." + if (const ReferenceType *Ref = T->getAs<ReferenceType>()) + T = Ref->getPointeeType(); + // Get information about the alignment. unsigned CharSize = Info.Ctx.Target.getCharWidth(); @@ -1257,10 +1264,11 @@ 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<DeclRefExpr>(E)) - return Info.Ctx.getDeclAlignInBytes(DRE->getDecl()); + return Info.Ctx.getDeclAlignInBytes(DRE->getDecl(), /*RefAsPointee*/true); if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) - return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl()); + return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl(), + /*RefAsPointee*/true); return GetAlignOfType(E->getType()); } @@ -1280,6 +1288,12 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { } QualType SrcTy = E->getTypeOfArgument(); + // C++ [expr.sizeof]p2: "When applied to a reference or a reference type, + // the result is the size of the referenced type." + // C++ [expr.alignof]p3: "When alignof is applied to a reference type, the + // result shall be the alignment of the referenced type." + if (const ReferenceType *Ref = SrcTy->getAs<ReferenceType>()) + SrcTy = Ref->getPointeeType(); // sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc // extension. |