forked from OSchip/llvm-project
Vectors are not integer types, so the type system should not classify
them as such. Type::is(Signed|Unsigned|)IntegerType() now return false for vector types, and new functions has(Signed|Unsigned|)IntegerRepresentation() cover integer types and vector-of-integer types. This fixes a bunch of latent bugs. Patch from Anton Yartsev! llvm-svn: 109229
This commit is contained in:
parent
572404311a
commit
5cc2c8b9c3
|
@ -273,6 +273,9 @@ public:
|
|||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isArrayType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasPointerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasObjCPointerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasSignedIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasUnsignedIntegerRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasFloatingRepresentation)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isPromotableIntegerType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSignedIntegerType)
|
||||
|
|
|
@ -952,10 +952,22 @@ public:
|
|||
/// an objective pointer type for the purpose of GC'ability
|
||||
bool hasObjCPointerRepresentation() const;
|
||||
|
||||
/// \brief Determine whether this type has an integer representation
|
||||
/// of some sort, e.g., it is an integer type or a vector.
|
||||
bool hasIntegerRepresentation() const;
|
||||
|
||||
/// \brief Determine whether this type has an signed integer representation
|
||||
/// of some sort, e.g., it is an signed integer type or a vector.
|
||||
bool hasSignedIntegerRepresentation() const;
|
||||
|
||||
/// \brief Determine whether this type has an unsigned integer representation
|
||||
/// of some sort, e.g., it is an unsigned integer type or a vector.
|
||||
bool hasUnsignedIntegerRepresentation() const;
|
||||
|
||||
/// \brief Determine whether this type has a floating-point representation
|
||||
/// of some sort, e.g., it is a floating-point type or a vector thereof.
|
||||
bool hasFloatingRepresentation() const;
|
||||
|
||||
|
||||
// Type Checking Functions: Check to see if this type is structurally the
|
||||
// specified type, ignoring typedefs and qualifiers, and return a pointer to
|
||||
// the best type we can.
|
||||
|
|
|
@ -5031,7 +5031,7 @@ unsigned ASTContext::getIntWidth(QualType T) {
|
|||
}
|
||||
|
||||
QualType ASTContext::getCorrespondingUnsignedType(QualType T) {
|
||||
assert(T->isSignedIntegerType() && "Unexpected type");
|
||||
assert(T->hasSignedIntegerRepresentation() && "Unexpected type");
|
||||
|
||||
// Turn <4 x signed int> -> <4 x unsigned int>
|
||||
if (const VectorType *VTy = T->getAs<VectorType>())
|
||||
|
@ -5411,8 +5411,8 @@ ASTContext::UsualArithmeticConversionsType(QualType lhs, QualType rhs) {
|
|||
// Finally, we have two differing integer types.
|
||||
// The rules for this case are in C99 6.3.1.8
|
||||
int compare = getIntegerTypeOrder(lhs, rhs);
|
||||
bool lhsSigned = lhs->isSignedIntegerType(),
|
||||
rhsSigned = rhs->isSignedIntegerType();
|
||||
bool lhsSigned = lhs->hasSignedIntegerRepresentation(),
|
||||
rhsSigned = rhs->hasSignedIntegerRepresentation();
|
||||
QualType destType;
|
||||
if (lhsSigned == rhsSigned) {
|
||||
// Same signedness; use the higher-ranked type
|
||||
|
|
|
@ -434,9 +434,14 @@ bool Type::isIntegerType() const {
|
|||
// FIXME: In C++, enum types are never integer types.
|
||||
if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::hasIntegerRepresentation() const {
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
return VT->getElementType()->isIntegerType();
|
||||
return false;
|
||||
else
|
||||
return isIntegerType();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this type is an integral type.
|
||||
|
@ -523,8 +528,7 @@ bool Type::isAnyCharacterType() const {
|
|||
|
||||
/// isSignedIntegerType - Return true if this is an integer type that is
|
||||
/// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..],
|
||||
/// an enum decl which has a signed representation, or a vector of signed
|
||||
/// integer element type.
|
||||
/// an enum decl which has a signed representation
|
||||
bool Type::isSignedIntegerType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
|
||||
return BT->getKind() >= BuiltinType::Char_S &&
|
||||
|
@ -534,15 +538,19 @@ bool Type::isSignedIntegerType() const {
|
|||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::hasSignedIntegerRepresentation() const {
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
return VT->getElementType()->isSignedIntegerType();
|
||||
return false;
|
||||
else
|
||||
return isSignedIntegerType();
|
||||
}
|
||||
|
||||
/// isUnsignedIntegerType - Return true if this is an integer type that is
|
||||
/// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum
|
||||
/// decl which has an unsigned representation, or a vector of unsigned integer
|
||||
/// element type.
|
||||
/// decl which has an unsigned representation
|
||||
bool Type::isUnsignedIntegerType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) {
|
||||
return BT->getKind() >= BuiltinType::Bool &&
|
||||
|
@ -552,9 +560,14 @@ bool Type::isUnsignedIntegerType() const {
|
|||
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
|
||||
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Type::hasUnsignedIntegerRepresentation() const {
|
||||
if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType))
|
||||
return VT->getElementType()->isUnsignedIntegerType();
|
||||
return false;
|
||||
else
|
||||
return isUnsignedIntegerType();
|
||||
}
|
||||
|
||||
bool Type::isFloatingType() const {
|
||||
|
|
|
@ -730,9 +730,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
|
|||
const ABIArgInfo &RetAI = FI.getReturnInfo();
|
||||
switch (RetAI.getKind()) {
|
||||
case ABIArgInfo::Extend:
|
||||
if (RetTy->isSignedIntegerType()) {
|
||||
if (RetTy->hasSignedIntegerRepresentation()) {
|
||||
RetAttrs |= llvm::Attribute::SExt;
|
||||
} else if (RetTy->isUnsignedIntegerType()) {
|
||||
} else if (RetTy->hasUnsignedIntegerRepresentation()) {
|
||||
RetAttrs |= llvm::Attribute::ZExt;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
|
|
|
@ -297,7 +297,7 @@ public:
|
|||
|
||||
// Binary Operators.
|
||||
Value *EmitMul(const BinOpInfo &Ops) {
|
||||
if (Ops.Ty->isSignedIntegerType()) {
|
||||
if (Ops.Ty->hasSignedIntegerRepresentation()) {
|
||||
switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
|
||||
case LangOptions::SOB_Undefined:
|
||||
return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
|
||||
|
@ -1422,7 +1422,7 @@ Value *ScalarExprEmitter::EmitCompoundAssign(const CompoundAssignOperator *E,
|
|||
Value *ScalarExprEmitter::EmitDiv(const BinOpInfo &Ops) {
|
||||
if (Ops.LHS->getType()->isFPOrFPVectorTy())
|
||||
return Builder.CreateFDiv(Ops.LHS, Ops.RHS, "div");
|
||||
else if (Ops.Ty->isUnsignedIntegerType())
|
||||
else if (Ops.Ty->hasUnsignedIntegerRepresentation())
|
||||
return Builder.CreateUDiv(Ops.LHS, Ops.RHS, "div");
|
||||
else
|
||||
return Builder.CreateSDiv(Ops.LHS, Ops.RHS, "div");
|
||||
|
@ -1523,7 +1523,7 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
|
|||
|
||||
Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
|
||||
if (!Ops.Ty->isAnyPointerType()) {
|
||||
if (Ops.Ty->isSignedIntegerType()) {
|
||||
if (Ops.Ty->hasSignedIntegerRepresentation()) {
|
||||
switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
|
||||
case LangOptions::SOB_Undefined:
|
||||
return Builder.CreateNSWAdd(Ops.LHS, Ops.RHS, "add");
|
||||
|
@ -1606,7 +1606,7 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) {
|
|||
|
||||
Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) {
|
||||
if (!isa<llvm::PointerType>(Ops.LHS->getType())) {
|
||||
if (Ops.Ty->isSignedIntegerType()) {
|
||||
if (Ops.Ty->hasSignedIntegerRepresentation()) {
|
||||
switch (CGF.getContext().getLangOptions().getSignedOverflowBehavior()) {
|
||||
case LangOptions::SOB_Undefined:
|
||||
return Builder.CreateNSWSub(Ops.LHS, Ops.RHS, "sub");
|
||||
|
@ -1747,7 +1747,7 @@ Value *ScalarExprEmitter::EmitShr(const BinOpInfo &Ops) {
|
|||
CGF.EmitBlock(Cont);
|
||||
}
|
||||
|
||||
if (Ops.Ty->isUnsignedIntegerType())
|
||||
if (Ops.Ty->hasUnsignedIntegerRepresentation())
|
||||
return Builder.CreateLShr(Ops.LHS, RHS, "shr");
|
||||
return Builder.CreateAShr(Ops.LHS, RHS, "shr");
|
||||
}
|
||||
|
@ -1791,7 +1791,7 @@ Value *ScalarExprEmitter::EmitCompare(const BinaryOperator *E,unsigned UICmpOpc,
|
|||
if (LHS->getType()->isFPOrFPVectorTy()) {
|
||||
Result = Builder.CreateFCmp((llvm::CmpInst::Predicate)FCmpOpc,
|
||||
LHS, RHS, "cmp");
|
||||
} else if (LHSTy->isSignedIntegerType()) {
|
||||
} else if (LHSTy->hasSignedIntegerRepresentation()) {
|
||||
Result = Builder.CreateICmp((llvm::ICmpInst::Predicate)SICmpOpc,
|
||||
LHS, RHS, "cmp");
|
||||
} else {
|
||||
|
|
|
@ -780,7 +780,7 @@ Action::OwningExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {
|
|||
// with mask. If so, verify that RHS is an integer vector type with the
|
||||
// same number of elts as lhs.
|
||||
if (TheCall->getNumArgs() == 2) {
|
||||
if (!RHSType->isIntegerType() ||
|
||||
if (!RHSType->hasIntegerRepresentation() ||
|
||||
RHSType->getAs<VectorType>()->getNumElements() != numElements)
|
||||
Diag(TheCall->getLocStart(), diag::err_shufflevector_incompatible_vector)
|
||||
<< SourceRange(TheCall->getArg(1)->getLocStart(),
|
||||
|
@ -2453,7 +2453,7 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
|
|||
// We don't do anything special if this isn't an unsigned integral
|
||||
// comparison: we're only interested in integral comparisons, and
|
||||
// signed comparisons only happen in cases we don't care to warn about.
|
||||
if (!T->isUnsignedIntegerType())
|
||||
if (!T->hasUnsignedIntegerRepresentation())
|
||||
return AnalyzeImpConvsInComparison(S, E);
|
||||
|
||||
Expr *lex = E->getLHS()->IgnoreParenImpCasts();
|
||||
|
@ -2462,12 +2462,12 @@ void AnalyzeComparison(Sema &S, BinaryOperator *E) {
|
|||
// Check to see if one of the (unmodified) operands is of different
|
||||
// signedness.
|
||||
Expr *signedOperand, *unsignedOperand;
|
||||
if (lex->getType()->isSignedIntegerType()) {
|
||||
assert(!rex->getType()->isSignedIntegerType() &&
|
||||
if (lex->getType()->hasSignedIntegerRepresentation()) {
|
||||
assert(!rex->getType()->hasSignedIntegerRepresentation() &&
|
||||
"unsigned comparison between two signed integer expressions?");
|
||||
signedOperand = lex;
|
||||
unsignedOperand = rex;
|
||||
} else if (rex->getType()->isSignedIntegerType()) {
|
||||
} else if (rex->getType()->hasSignedIntegerRepresentation()) {
|
||||
signedOperand = rex;
|
||||
unsignedOperand = lex;
|
||||
} else {
|
||||
|
|
|
@ -2362,8 +2362,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
|
|||
<< LHSExp->getSourceRange() << RHSExp->getSourceRange());
|
||||
}
|
||||
// C99 6.5.2.1p1
|
||||
if (!(IndexExpr->getType()->isIntegerType() &&
|
||||
IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
|
||||
if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
|
||||
return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
|
||||
<< IndexExpr->getSourceRange());
|
||||
|
||||
|
@ -4576,12 +4575,12 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
|
|||
// "unsigned char" on systems where "char" is unsigned.
|
||||
if (lhptee->isCharType())
|
||||
lhptee = Context.UnsignedCharTy;
|
||||
else if (lhptee->isSignedIntegerType())
|
||||
else if (lhptee->hasSignedIntegerRepresentation())
|
||||
lhptee = Context.getCorrespondingUnsignedType(lhptee);
|
||||
|
||||
if (rhptee->isCharType())
|
||||
rhptee = Context.UnsignedCharTy;
|
||||
else if (rhptee->isSignedIntegerType())
|
||||
else if (rhptee->hasSignedIntegerRepresentation())
|
||||
rhptee = Context.getCorrespondingUnsignedType(rhptee);
|
||||
|
||||
if (lhptee == rhptee) {
|
||||
|
@ -5078,7 +5077,8 @@ QualType Sema::CheckMultiplyDivideOperands(
|
|||
QualType Sema::CheckRemainderOperands(
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
|
||||
if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
|
||||
if (lex->getType()->hasIntegerRepresentation() &&
|
||||
rex->getType()->hasIntegerRepresentation())
|
||||
return CheckVectorOperands(Loc, lex, rex);
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
}
|
||||
|
@ -5323,7 +5323,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
|
|||
QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
|
||||
bool isCompAssign) {
|
||||
// C99 6.5.7p2: Each of the operands shall have integer type.
|
||||
if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
|
||||
if (!lex->getType()->hasIntegerRepresentation() ||
|
||||
!rex->getType()->hasIntegerRepresentation())
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
|
||||
// Vector shifts promote their scalar inputs to vector type.
|
||||
|
@ -5777,7 +5778,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
|
|||
// Return the type for the comparison, which is the same as vector type for
|
||||
// integer vectors, or an integer type of identical size and number of
|
||||
// elements for floating point vectors.
|
||||
if (lType->isIntegerType())
|
||||
if (lType->hasIntegerRepresentation())
|
||||
return lType;
|
||||
|
||||
const VectorType *VTy = lType->getAs<VectorType>();
|
||||
|
@ -5794,8 +5795,13 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
|
|||
|
||||
inline QualType Sema::CheckBitwiseOperands(
|
||||
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
|
||||
return CheckVectorOperands(Loc, lex, rex);
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
|
||||
if (lex->getType()->hasIntegerRepresentation() &&
|
||||
rex->getType()->hasIntegerRepresentation())
|
||||
return CheckVectorOperands(Loc, lex, rex);
|
||||
|
||||
return InvalidOperands(Loc, lex, rex);
|
||||
}
|
||||
|
||||
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
|
||||
|
||||
|
@ -6702,7 +6708,7 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
|
|||
// C99 does not support '~' for complex conjugation.
|
||||
Diag(OpLoc, diag::ext_integer_complement_complex)
|
||||
<< resultType << Input->getSourceRange();
|
||||
else if (!resultType->isIntegerType())
|
||||
else if (!resultType->hasIntegerRepresentation())
|
||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
|
||||
<< resultType << Input->getSourceRange());
|
||||
break;
|
||||
|
|
|
@ -967,9 +967,8 @@ Sema::OwningExprResult Sema::BuildInstanceMessage(ExprArg ReceiverE,
|
|||
if (Method && DiagnoseUseOfDecl(Method, Loc))
|
||||
return ExprError();
|
||||
} else if (!Context.getObjCIdType().isNull() &&
|
||||
(ReceiverType->isPointerType() ||
|
||||
(ReceiverType->isIntegerType() &&
|
||||
ReceiverType->isScalarType()))) {
|
||||
(ReceiverType->isPointerType() ||
|
||||
ReceiverType->isIntegerType())) {
|
||||
// Implicitly convert integers and pointers to 'id' but emit a warning.
|
||||
Diag(Loc, diag::warn_bad_receiver_type)
|
||||
<< ReceiverType
|
||||
|
|
|
@ -1944,8 +1944,7 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
|
|||
return;
|
||||
}
|
||||
// the base type must be integer or float, and can't already be a vector.
|
||||
if (CurType->isVectorType() ||
|
||||
(!CurType->isIntegerType() && !CurType->isRealFloatingType())) {
|
||||
if (!CurType->isIntegerType() && !CurType->isRealFloatingType()) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType;
|
||||
Attr.setInvalid();
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// RUN: %clang_cc1 %s -verify -fsyntax-only -Wvector-conversions
|
||||
typedef unsigned int v2u __attribute__ ((vector_size (8)));
|
||||
typedef int v2s __attribute__ ((vector_size (8)));
|
||||
typedef float v2f __attribute__ ((vector_size(8)));
|
||||
|
||||
void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
|
||||
// Bitwise binary operators
|
||||
(void)(v2ua & v2ua);
|
||||
(void)(v2fa & v2fa); // expected-error{{invalid operands to binary expression}}
|
||||
|
||||
// Unary operators
|
||||
(void)(~v2ua);
|
||||
(void)(~v2fa); // expected-error{{invalid argument type 'v2f' to unary}}
|
||||
|
||||
// Arrays
|
||||
int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u'}}
|
||||
int array2[17];
|
||||
// FIXME: error message below needs type!
|
||||
(void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
|
||||
|
||||
v2u *v2u_ptr = 0;
|
||||
v2s *v2s_ptr;
|
||||
v2s_ptr = v2u_ptr; // expected-warning{{converts between pointers to integer types with different sign}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue