зеркало из https://github.com/microsoft/clang-1.git
Minor enhancements to Evaluate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67503 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c110c54581
Коммит
a1f47c447a
|
@ -71,7 +71,7 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
|
||||||
return false;
|
return false;
|
||||||
Result = !FloatResult.isZero();
|
Result = !FloatResult.isZero();
|
||||||
return true;
|
return true;
|
||||||
} else if (E->getType()->isPointerType()) {
|
} else if (E->getType()->hasPointerRepresentation()) {
|
||||||
APValue PointerResult;
|
APValue PointerResult;
|
||||||
if (!EvaluatePointer(E, PointerResult, Info))
|
if (!EvaluatePointer(E, PointerResult, Info))
|
||||||
return false;
|
return false;
|
||||||
|
@ -79,8 +79,19 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
|
||||||
// the check look like?
|
// the check look like?
|
||||||
Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset();
|
Result = PointerResult.getLValueBase() || PointerResult.getLValueOffset();
|
||||||
return true;
|
return true;
|
||||||
|
} else if (E->getType()->isAnyComplexType()) {
|
||||||
|
APValue ComplexResult;
|
||||||
|
if (!EvaluateComplex(E, ComplexResult, Info))
|
||||||
|
return false;
|
||||||
|
if (ComplexResult.isComplexFloat()) {
|
||||||
|
Result = !ComplexResult.getComplexFloatReal().isZero() ||
|
||||||
|
!ComplexResult.getComplexFloatImag().isZero();
|
||||||
|
} else {
|
||||||
|
Result = ComplexResult.getComplexIntReal().getBoolValue() ||
|
||||||
|
ComplexResult.getComplexIntImag().getBoolValue();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// FIXME: Handle pointer-like types, complex types
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -890,21 +901,22 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
APValue LHSValue;
|
APValue LHSValue;
|
||||||
if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
|
if (!EvaluatePointer(E->getLHS(), LHSValue, Info))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
APValue RHSValue;
|
APValue RHSValue;
|
||||||
if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
|
if (!EvaluatePointer(E->getRHS(), RHSValue, Info))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// FIXME: Is this correct? What if only one of the operands has a base?
|
// Reject any bases; this is conservative, but good enough for
|
||||||
|
// common uses
|
||||||
if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
|
if (LHSValue.getLValueBase() || RHSValue.getLValueBase())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const QualType Type = E->getLHS()->getType();
|
const QualType Type = E->getLHS()->getType();
|
||||||
const QualType ElementType = Type->getAsPointerType()->getPointeeType();
|
const QualType ElementType = Type->getAsPointerType()->getPointeeType();
|
||||||
|
|
||||||
uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
|
uint64_t D = LHSValue.getLValueOffset() - RHSValue.getLValueOffset();
|
||||||
D /= Info.Ctx.getTypeSize(ElementType) / 8;
|
D /= Info.Ctx.getTypeSize(ElementType) / 8;
|
||||||
|
|
||||||
return Success(D, E);
|
return Success(D, E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -980,20 +992,20 @@ unsigned IntExprEvaluator::GetAlignOfType(QualType T) {
|
||||||
// __alignof__(void) = 1 as a gcc extension.
|
// __alignof__(void) = 1 as a gcc extension.
|
||||||
if (Ty->isVoidType())
|
if (Ty->isVoidType())
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// GCC extension: alignof(function) = 4.
|
// GCC extension: alignof(function) = 4.
|
||||||
// FIXME: AlignOf shouldn't be unconditionally 4! It should listen to the
|
// FIXME: AlignOf shouldn't be unconditionally 4! It should listen to the
|
||||||
// attribute(align) directive.
|
// attribute(align) directive.
|
||||||
if (Ty->isFunctionType())
|
if (Ty->isFunctionType())
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty))
|
if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(Ty))
|
||||||
return GetAlignOfType(QualType(EXTQT->getBaseType(), 0));
|
return GetAlignOfType(QualType(EXTQT->getBaseType(), 0));
|
||||||
|
|
||||||
// alignof VLA/incomplete array.
|
// alignof VLA/incomplete array.
|
||||||
if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty))
|
if (const ArrayType *VAT = dyn_cast<ArrayType>(Ty))
|
||||||
return GetAlignOfType(VAT->getElementType());
|
return GetAlignOfType(VAT->getElementType());
|
||||||
|
|
||||||
// sizeof (objc class)?
|
// sizeof (objc class)?
|
||||||
if (isa<ObjCInterfaceType>(Ty))
|
if (isa<ObjCInterfaceType>(Ty))
|
||||||
return 1; // FIXME: This probably isn't right.
|
return 1; // FIXME: This probably isn't right.
|
||||||
|
@ -1010,7 +1022,7 @@ unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) {
|
||||||
// to 1 in those cases.
|
// to 1 in those cases.
|
||||||
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
|
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
|
||||||
return Info.Ctx.getDeclAlignInBytes(DRE->getDecl());
|
return Info.Ctx.getDeclAlignInBytes(DRE->getDecl());
|
||||||
|
|
||||||
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
|
if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
|
||||||
return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl());
|
return Info.Ctx.getDeclAlignInBytes(ME->getMemberDecl());
|
||||||
|
|
||||||
|
@ -1030,14 +1042,14 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
|
||||||
else
|
else
|
||||||
return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
|
return Success(GetAlignOfExpr(E->getArgumentExpr()), E);
|
||||||
}
|
}
|
||||||
|
|
||||||
QualType SrcTy = E->getTypeOfArgument();
|
QualType SrcTy = E->getTypeOfArgument();
|
||||||
|
|
||||||
// sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
|
// sizeof(void), __alignof__(void), sizeof(function) = 1 as a gcc
|
||||||
// extension.
|
// extension.
|
||||||
if (SrcTy->isVoidType() || SrcTy->isFunctionType())
|
if (SrcTy->isVoidType() || SrcTy->isFunctionType())
|
||||||
return Success(1, E);
|
return Success(1, E);
|
||||||
|
|
||||||
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
// sizeof(vla) is not a constantexpr: C99 6.5.3.4p2.
|
||||||
if (!SrcTy->isConstantSizeType())
|
if (!SrcTy->isConstantSizeType())
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -50,3 +50,8 @@ EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1);
|
||||||
int g23[(int)(1.0 / 1.0)] = { 1 };
|
int g23[(int)(1.0 / 1.0)] = { 1 };
|
||||||
int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}}
|
int g24[(int)(1.0 / 1.0)] = { 1 , 2 }; // expected-warning {{excess elements in array initializer}}
|
||||||
int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);
|
int g25[(int)(1.0 + 1.0)], g26 = sizeof(g25);
|
||||||
|
|
||||||
|
EVAL_EXPR(26, (_Complex double)0 ? -1 : 1)
|
||||||
|
EVAL_EXPR(27, (_Complex int)0 ? -1 : 1)
|
||||||
|
EVAL_EXPR(28, (_Complex double)1 ? 1 : -1)
|
||||||
|
EVAL_EXPR(29, (_Complex int)1 ? 1 : -1)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче