summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-10-26 19:26:45 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-10-26 19:26:45 +0000
commit6822bd79ac43f267613f1615bf60407103e24dba (patch)
tree3f29df66730f2992292de2bfd5e2913696043b6f /clang/lib/AST/ExprConstant.cpp
parent9e22b4c76d7214002e446d28b5fa31102b529e99 (diff)
downloadbcm5719-llvm-6822bd79ac43f267613f1615bf60407103e24dba.tar.gz
bcm5719-llvm-6822bd79ac43f267613f1615bf60407103e24dba.zip
PR26547: alignof should return ABI alignment, not preferred alignment
Summary: - Add `UETT_PreferredAlignOf` to account for the difference between `__alignof` and `alignof` - `AlignOfType` now returns ABI alignment instead of preferred alignment iff clang-abi-compat > 7, and one uses _Alignof or alignof Patch by Nicole Mazzuca! Differential Revision: https://reviews.llvm.org/D53207 llvm-svn: 345419
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp37
1 files changed, 27 insertions, 10 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c64e335255e..d5bbbd2b57c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -5946,21 +5946,35 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
return ExprEvaluatorBaseTy::VisitCastExpr(E);
}
-static CharUnits GetAlignOfType(EvalInfo &Info, QualType T) {
+static CharUnits GetAlignOfType(EvalInfo &Info, QualType T,
+ UnaryExprOrTypeTrait ExprKind) {
// C++ [expr.alignof]p3:
// When alignof is applied to a reference type, the result is the
// alignment of the referenced type.
if (const ReferenceType *Ref = T->getAs<ReferenceType>())
T = Ref->getPointeeType();
- // __alignof is defined to return the preferred alignment.
if (T.getQualifiers().hasUnaligned())
return CharUnits::One();
- return Info.Ctx.toCharUnitsFromBits(
- Info.Ctx.getPreferredTypeAlign(T.getTypePtr()));
+
+ const bool AlignOfReturnsPreferred =
+ Info.Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
+
+ // __alignof is defined to return the preferred alignment.
+ // Before 8, clang returned the preferred alignment for alignof and _Alignof
+ // as well.
+ if (ExprKind == UETT_PreferredAlignOf || AlignOfReturnsPreferred)
+ return Info.Ctx.toCharUnitsFromBits(
+ Info.Ctx.getPreferredTypeAlign(T.getTypePtr()));
+ // alignof and _Alignof are defined to return the ABI alignment.
+ else if (ExprKind == UETT_AlignOf)
+ return Info.Ctx.getTypeAlignInChars(T.getTypePtr());
+ else
+ llvm_unreachable("GetAlignOfType on a non-alignment ExprKind");
}
-static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E) {
+static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E,
+ UnaryExprOrTypeTrait ExprKind) {
E = E->IgnoreParens();
// The kinds of expressions that we have special-case logic here for
@@ -5977,7 +5991,7 @@ static CharUnits GetAlignOfExpr(EvalInfo &Info, const Expr *E) {
return Info.Ctx.getDeclAlign(ME->getMemberDecl(),
/*RefAsPointee*/true);
- return GetAlignOfType(Info, E->getType());
+ return GetAlignOfType(Info, E->getType(), ExprKind);
}
// To be clear: this happily visits unsupported builtins. Better name welcomed.
@@ -6038,8 +6052,8 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
OffsetResult.Base.dyn_cast<const ValueDecl*>()) {
BaseAlignment = Info.Ctx.getDeclAlign(VD);
} else {
- BaseAlignment =
- GetAlignOfExpr(Info, OffsetResult.Base.get<const Expr*>());
+ BaseAlignment = GetAlignOfExpr(
+ Info, OffsetResult.Base.get<const Expr *>(), UETT_AlignOf);
}
if (BaseAlignment < Align) {
@@ -9358,11 +9372,14 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
bool IntExprEvaluator::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *E) {
switch(E->getKind()) {
+ case UETT_PreferredAlignOf:
case UETT_AlignOf: {
if (E->isArgumentType())
- return Success(GetAlignOfType(Info, E->getArgumentType()), E);
+ return Success(GetAlignOfType(Info, E->getArgumentType(), E->getKind()),
+ E);
else
- return Success(GetAlignOfExpr(Info, E->getArgumentExpr()), E);
+ return Success(GetAlignOfExpr(Info, E->getArgumentExpr(), E->getKind()),
+ E);
}
case UETT_VecStep: {
OpenPOWER on IntegriCloud