From 0e5eb62fd6989e651a0e8d073ad32fe2efa24408 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 7 Jan 2014 07:59:31 +0000 Subject: [PATCH] For areVectorOperandsLaxBitCastable(), only return false if both opearands are vector types and add a diagnostic when the operand is a vector and non-scalar value. rdar://15722301 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@198680 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Sema/SemaExpr.cpp | 32 ++++++++++++---------- test/SemaCXX/vector-casts.cpp | 10 ++++++- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 255d4db92d..1ae6d2f143 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1869,6 +1869,8 @@ def err_attribute_zero_size : Error<"zero vector size">; def err_attribute_size_too_large : Error<"vector size too large">; def err_typecheck_vector_not_convertable : Error< "can't convert between vector values of different size (%0 and %1)">; +def err_typecheck_vector_not_convertable_non_scalar : Error< + "can't convert between vector and non-scalar values (%0 and %1)">; def err_ext_vector_component_exceeds_length : Error< "vector component access exceeds type %0">; def err_ext_vector_component_name_illegal : Error< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 842e11b6d1..36250839cf 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6617,6 +6617,9 @@ static bool areVectorOperandsLaxBitCastable(ASTContext &Ctx, if (!Ctx.getLangOpts().LaxVectorConversions) return false; + if (!LHSType->isVectorType() || !RHSType->isVectorType()) + return false; + unsigned LHSSize = Ctx.getTypeSize(LHSType); unsigned RHSSize = Ctx.getTypeSize(RHSType); if (LHSSize != RHSSize) @@ -6628,20 +6631,13 @@ static bool areVectorOperandsLaxBitCastable(ASTContext &Ctx, // Make sure such width is the same between the types, otherwise we may end // up with an invalid bitcast. unsigned LHSIRSize, RHSIRSize; - if (LHSType->isVectorType()) { - const VectorType *Vec = LHSType->getAs(); - LHSIRSize = Vec->getNumElements() * - Ctx.getTypeSize(Vec->getElementType()); - } else { - LHSIRSize = LHSSize; - } - if (RHSType->isVectorType()) { - const VectorType *Vec = RHSType->getAs(); - RHSIRSize = Vec->getNumElements() * - Ctx.getTypeSize(Vec->getElementType()); - } else { - RHSIRSize = RHSSize; - } + const VectorType *LVec = LHSType->getAs(); + LHSIRSize = LVec->getNumElements() * + Ctx.getTypeSize(LVec->getElementType()); + const VectorType *RVec = RHSType->getAs(); + RHSIRSize = RVec->getNumElements() * + Ctx.getTypeSize(RVec->getElementType()); + if (LHSIRSize != RHSIRSize) return false; @@ -6692,6 +6688,14 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, return LHSType; } + if (!(LHSType->isVectorType() || LHSType->isScalarType()) || + !(RHSType->isVectorType() || RHSType->isScalarType())) { + Diag(Loc, diag::err_typecheck_vector_not_convertable_non_scalar) + << LHS.get()->getType() << RHS.get()->getType() + << LHS.get()->getSourceRange() << RHS.get()->getSourceRange(); + return QualType(); + } + // Canonicalize the ExtVector to the LHS, remember if we swapped so we can // swap back (so that we don't reverse the inputs to a subtract, for instance. bool swapped = false; diff --git a/test/SemaCXX/vector-casts.cpp b/test/SemaCXX/vector-casts.cpp index 681a07ea47..25c59e6427 100644 --- a/test/SemaCXX/vector-casts.cpp +++ b/test/SemaCXX/vector-casts.cpp @@ -37,4 +37,12 @@ void f() { (void)(__v4hi)v8hi; // expected-error {{C-style cast from vector '__v8hi' to vector '__v4hi' of different size}} } - +struct testvec { + __v2si v; + void madd(const testvec& rhs) { + v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}} + } + void madd2(testvec rhs) { + v = v + rhs; // expected-error {{can't convert between vector and non-scalar values}} + } +}; -- 2.40.0