diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 7 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 36 |
2 files changed, 41 insertions, 2 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 36f3ff96f3b..48e67723539 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -3063,6 +3063,13 @@ public: // returns true if the cast is invalid bool CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty); + // CheckExtVectorCast - check type constraints for extended vectors. + // Since vectors are an extension, there are no C standard reference for this. + // We allow casting between vectors and integer datatypes of the same size, + // or vectors and the element type of that vector. + // returns true if the cast is invalid + bool CheckExtVectorCast(SourceRange R, QualType VectorTy, QualType Ty); + /// CheckMessageArgumentTypes - Check types in an Obj-C message send. /// \param Method - May be null. /// \param [out] ReturnType - The return type of the send. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a01fbb1e66b..3d223213865 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2876,12 +2876,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr) { return Diag(castExpr->getLocStart(), diag::err_typecheck_expect_scalar_operand) << castExpr->getType() << castExpr->getSourceRange(); - } else if (castExpr->getType()->isVectorType()) { - if (CheckVectorCast(TyR, castExpr->getType(), castType)) + } else if (castType->isExtVectorType()) { + if (CheckExtVectorCast(TyR, castType, castExpr->getType())) return true; } else if (castType->isVectorType()) { if (CheckVectorCast(TyR, castType, castExpr->getType())) return true; + } else if (castExpr->getType()->isVectorType()) { + if (CheckVectorCast(TyR, castExpr->getType(), castType)) + return true; } else if (getLangOptions().ObjC1 && isa<ObjCSuperExpr>(castExpr)) { return Diag(castExpr->getLocStart(), diag::err_illegal_super_cast) << TyR; } else if (!castType->isArithmeticType()) { @@ -2919,6 +2922,35 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty) { return false; } +bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, QualType SrcTy) { + assert(DestTy->isExtVectorType() && "Not an extended vector type!"); + + // If SrcTy is also an ExtVectorType, the types must be identical unless + // lax vector conversions is enabled. + if (SrcTy->isExtVectorType()) { + if (getLangOptions().LaxVectorConversions && + Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) + return false; + if (DestTy != SrcTy) + return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) + << DestTy << SrcTy << R; + return false; + } + + // If SrcTy is a VectorType, then only the total size must match. + if (SrcTy->isVectorType()) { + if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy)) + return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors) + << DestTy << SrcTy << R; + return false; + } + + // All scalar -> ext vector "c-style" casts are legal; the appropriate + // conversion will take place first from scalar to elt type, and then + // splat from elt type to vector. + return false; +} + Action::OwningExprResult Sema::ActOnCastExpr(SourceLocation LParenLoc, TypeTy *Ty, SourceLocation RParenLoc, ExprArg Op) { |

