summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Expr.cpp3
-rw-r--r--clang/lib/AST/ExprConstant.cpp7
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp1
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp1
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp1
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp25
-rw-r--r--clang/lib/Edit/RewriteObjCFoundationAPI.cpp3
-rw-r--r--clang/lib/Sema/SemaCast.cpp2
-rw-r--r--clang/lib/Sema/SemaChecking.cpp3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp54
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp17
-rw-r--r--clang/lib/Sema/SemaOverload.cpp1
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp4
14 files changed, 79 insertions, 44 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index f9757b20929..52f34df4356 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1553,6 +1553,7 @@ bool CastExpr::CastConsistency() const {
case CK_ToVoid:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
case CK_FloatingCast:
@@ -1646,6 +1647,8 @@ const char *CastExpr::getCastKindName() const {
return "VectorSplat";
case CK_IntegralCast:
return "IntegralCast";
+ case CK_BooleanToSignedIntegral:
+ return "BooleanToSignedIntegral";
case CK_IntegralToBoolean:
return "IntegralToBoolean";
case CK_IntegralToFloating:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index c4c4398c362..fa652ba1b0a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7781,12 +7781,16 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_PointerToBoolean:
case CK_IntegralToBoolean:
case CK_FloatingToBoolean:
+ case CK_BooleanToSignedIntegral:
case CK_FloatingComplexToBoolean:
case CK_IntegralComplexToBoolean: {
bool BoolResult;
if (!EvaluateAsBooleanCondition(SubExpr, BoolResult, Info))
return false;
- return Success(BoolResult, E);
+ uint64_t IntResult = BoolResult;
+ if (BoolResult && E->getCastKind() == CK_BooleanToSignedIntegral)
+ IntResult = (uint64_t)-1;
+ return Success(IntResult, E);
}
case CK_IntegralCast: {
@@ -8223,6 +8227,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_ToVoid:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index dabd2b1528b..507ce3d7d0c 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -3365,6 +3365,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_PointerToBoolean:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 20838db044c..a4547a9982b 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -721,6 +721,7 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
case CK_ToVoid:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index ccdb53287e9..22910d931de 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -462,6 +462,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_ToVoid:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 3839ab718fa..ee049f1810a 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -735,6 +735,7 @@ public:
case CK_PointerToBoolean:
case CK_NullToPointer:
case CK_IntegralCast:
+ case CK_BooleanToSignedIntegral:
case CK_IntegralToPointer:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 725d96f2987..268e7967b80 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -811,14 +811,15 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value *Src, QualType SrcType,
// A scalar can be splatted to an extended vector of the same element type
if (DstType->isExtVectorType() && !SrcType->isVectorType()) {
- // Cast the scalar to element type
- QualType EltTy = DstType->getAs<ExtVectorType>()->getElementType();
- llvm::Value *Elt = EmitScalarConversion(
- Src, SrcType, EltTy, Loc, CGF.getContext().getLangOpts().OpenCL);
+ // Sema should add casts to make sure that the source expression's type is
+ // the same as the vector's element type (sans qualifiers)
+ assert(DstType->castAs<ExtVectorType>()->getElementType().getTypePtr() ==
+ SrcType.getTypePtr() &&
+ "Splatted expr doesn't match with vector element type?");
// Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
- return Builder.CreateVectorSplat(NumElements, Elt, "splat");
+ return Builder.CreateVectorSplat(NumElements, Src, "splat");
}
// Allow bitcast from vector to integer/fp of the same size.
@@ -1541,15 +1542,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
}
case CK_VectorSplat: {
llvm::Type *DstTy = ConvertType(DestTy);
- // Need an IgnoreImpCasts here as by default a boolean will be promoted to
- // an int, which will not perform the sign extension, so if we know we are
- // going to cast to a vector we have to strip the implicit cast off.
- Value *Elt = Visit(const_cast<Expr*>(E->IgnoreImpCasts()));
- Elt = EmitScalarConversion(Elt, E->IgnoreImpCasts()->getType(),
- DestTy->getAs<VectorType>()->getElementType(),
- CE->getExprLoc(),
- CGF.getContext().getLangOpts().OpenCL);
-
+ Value *Elt = Visit(const_cast<Expr*>(E));
// Splat the element across to all elements
unsigned NumElements = cast<llvm::VectorType>(DstTy)->getNumElements();
return Builder.CreateVectorSplat(NumElements, Elt, "splat");
@@ -1561,6 +1554,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
case CK_FloatingCast:
return EmitScalarConversion(Visit(E), E->getType(), DestTy,
CE->getExprLoc());
+ case CK_BooleanToSignedIntegral:
+ return EmitScalarConversion(Visit(E), E->getType(), DestTy,
+ CE->getExprLoc(),
+ /*TreatBooleanAsSigned=*/true);
case CK_IntegralToBoolean:
return EmitIntToBoolConversion(Visit(E));
case CK_PointerToBoolean:
diff --git a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp
index 9f71168de8f..482c0f6f856 100644
--- a/clang/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/clang/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1077,6 +1077,9 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
case CK_BuiltinFnToFnPtr:
case CK_ZeroToOCLEvent:
return false;
+
+ case CK_BooleanToSignedIntegral:
+ llvm_unreachable("OpenCL-specific cast in Objective-C?");
}
}
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 07b058911c2..ad1d7da4d07 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -2105,6 +2105,7 @@ void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,
&& (SrcExpr.get()->getType()->isIntegerType()
|| SrcExpr.get()->getType()->isFloatingType())) {
Kind = CK_VectorSplat;
+ SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
return;
}
@@ -2339,6 +2340,7 @@ void CastOperation::CheckCStyleCast() {
if (DestVecTy->getVectorKind() == VectorType::AltiVecVector &&
(SrcType->isIntegerType() || SrcType->isFloatingType())) {
Kind = CK_VectorSplat;
+ SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());
} else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {
SrcExpr = ExprError();
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4680bcd11d0..6c2834b750a 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6243,7 +6243,8 @@ static IntRange GetExprRange(ASTContext &C, Expr *E, unsigned MaxWidth) {
IntRange OutputTypeRange = IntRange::forValueOfType(C, GetExprType(CE));
- bool isIntegerCast = (CE->getCastKind() == CK_IntegralCast);
+ bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
+ CE->getCastKind() == CK_BooleanToSignedIntegral;
// Assume that non-integer casts can span the full range of the type.
if (!isIntegerCast)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 361b0a1b72d..3e89af625d1 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -5602,6 +5602,39 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
return false;
}
+ExprResult Sema::prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr) {
+ QualType DestElemTy = VectorTy->castAs<VectorType>()->getElementType();
+
+ if (DestElemTy == SplattedExpr->getType())
+ return SplattedExpr;
+
+ assert(DestElemTy->isFloatingType() ||
+ DestElemTy->isIntegralOrEnumerationType());
+
+ CastKind CK;
+ if (VectorTy->isExtVectorType() && SplattedExpr->getType()->isBooleanType()) {
+ // OpenCL requires that we convert `true` boolean expressions to -1, but
+ // only when splatting vectors.
+ if (DestElemTy->isFloatingType()) {
+ // To avoid having to have a CK_BooleanToSignedFloating cast kind, we cast
+ // in two steps: boolean to signed integral, then to floating.
+ ExprResult CastExprRes = ImpCastExprToType(SplattedExpr, Context.IntTy,
+ CK_BooleanToSignedIntegral);
+ SplattedExpr = CastExprRes.get();
+ CK = CK_IntegralToFloating;
+ } else {
+ CK = CK_BooleanToSignedIntegral;
+ }
+ } else {
+ ExprResult CastExprRes = SplattedExpr;
+ CK = PrepareScalarCast(CastExprRes, DestElemTy);
+ if (CastExprRes.isInvalid())
+ return ExprError();
+ SplattedExpr = CastExprRes.get();
+ }
+ return ImpCastExprToType(SplattedExpr, DestElemTy, CK);
+}
+
ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
Expr *CastExpr, CastKind &Kind) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
@@ -5632,15 +5665,8 @@ ExprResult Sema::CheckExtVectorCast(SourceRange R, QualType DestTy,
diag::err_invalid_conversion_between_vector_and_scalar)
<< DestTy << SrcTy << R;
- QualType DestElemTy = DestTy->getAs<ExtVectorType>()->getElementType();
- ExprResult CastExprRes = CastExpr;
- CastKind CK = PrepareScalarCast(CastExprRes, DestElemTy);
- if (CastExprRes.isInvalid())
- return ExprError();
- CastExpr = ImpCastExprToType(CastExprRes.get(), DestElemTy, CK).get();
-
Kind = CK_VectorSplat;
- return CastExpr;
+ return prepareVectorSplat(DestTy, CastExpr);
}
ExprResult
@@ -6979,13 +7005,9 @@ Sema::CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (RHSType->isExtVectorType())
return Incompatible;
if (RHSType->isArithmeticType()) {
- // CK_VectorSplat does T -> vector T, so first cast to the
- // element type.
- QualType elType = cast<ExtVectorType>(LHSType)->getElementType();
- if (elType != RHSType && ConvertRHS) {
- Kind = PrepareScalarCast(RHS, elType);
- RHS = ImpCastExprToType(RHS.get(), elType, Kind);
- }
+ // CK_VectorSplat does T -> vector T, so first cast to the element type.
+ if (ConvertRHS)
+ RHS = prepareVectorSplat(LHSType, RHS.get());
Kind = CK_VectorSplat;
return Compatible;
}
@@ -8203,7 +8225,7 @@ static QualType checkOpenCLVectorShift(Sema &S,
if (RHS.isInvalid()) return QualType();
QualType LHSType = LHS.get()->getType();
- const VectorType *LHSVecTy = LHSType->getAs<VectorType>();
+ const VectorType *LHSVecTy = LHSType->castAs<VectorType>();
QualType LHSEleType = LHSVecTy->getElementType();
// Note that RHS might not be a vector.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 2ad595f3a81..38fbea18d79 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3353,20 +3353,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
VK_RValue, /*BasePath=*/nullptr, CCK).get();
break;
- case ICK_Vector_Splat:
+ case ICK_Vector_Splat: {
// Vector splat from any arithmetic type to a vector.
- // Cast to the element type.
- {
- QualType elType = ToType->getAs<ExtVectorType>()->getElementType();
- if (elType != From->getType()) {
- ExprResult E = From;
- From = ImpCastExprToType(From, elType,
- PrepareScalarCast(E, elType)).get();
- }
- From = ImpCastExprToType(From, ToType, CK_VectorSplat,
- VK_RValue, /*BasePath=*/nullptr, CCK).get();
- }
+ Expr *Elem = prepareVectorSplat(ToType, From).get();
+ From = ImpCastExprToType(Elem, ToType, CK_VectorSplat, VK_RValue,
+ /*BasePath=*/nullptr, CCK).get();
break;
+ }
case ICK_Complex_Real:
// Case 1. x -> _Complex y
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 682f3692bac..663da0c0e80 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -258,6 +258,7 @@ static const Expr *IgnoreNarrowingConversion(const Expr *Converted) {
case CK_IntegralCast:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
+ case CK_BooleanToSignedIntegral:
case CK_FloatingToIntegral:
case CK_FloatingToBoolean:
case CK_FloatingCast:
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 3a30b29781b..175225ba0de 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -316,6 +316,7 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
case CK_ArrayToPointerDecay:
case CK_BitCast:
case CK_AddressSpaceConversion:
+ case CK_BooleanToSignedIntegral:
case CK_NullToPointer:
case CK_IntegralToPointer:
case CK_PointerToIntegral:
@@ -344,6 +345,9 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
// Delegate to SValBuilder to process.
SVal V = state->getSVal(Ex, LCtx);
V = svalBuilder.evalCast(V, T, ExTy);
+ // Negate the result if we're treating the boolean as a signed i1
+ if (CastE->getCastKind() == CK_BooleanToSignedIntegral)
+ V = evalMinus(V);
state = state->BindExpr(CastE, LCtx, V);
Bldr.generateNode(CastE, Pred, state);
continue;
OpenPOWER on IntegriCloud