diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7567,6 +7567,12 @@ "'-altivec-compat=xl' option">, InGroup>; +def warn_deprecated_lax_vec_conv_all : Warning< + "Current bitcast for incompatible vector types (%0 and %1) are deprecated. " + "The default behaviour will change to what is implied by the " + "-fno-lax-vector-conversions option">, + InGroup>; + def err_catch_incomplete_ptr : Error< "cannot catch pointer to incomplete type %0">; def err_catch_incomplete_ref : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12047,6 +12047,8 @@ bool areVectorTypesSameSize(QualType srcType, QualType destType); bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); bool isLaxVectorConversion(QualType srcType, QualType destType); + bool areVectorTypesSameElmType(QualType srcType, QualType destType); + bool areAnyVectorTypesAltivec(QualType srcType, QualType destType); /// type checking declaration initializers (C99 6.7.8) bool CheckForConstantInitializer(Expr *e, QualType t); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -7712,6 +7712,43 @@ return (SrcLen * SrcEltSize == DestLen * DestEltSize); } +// This returns true if at least one of the types is an altivec vector. +bool Sema::areAnyVectorTypesAltivec(QualType SrcTy, QualType DestTy) { + assert((DestTy->isVectorType() || SrcTy->isVectorType()) && + "areAnyVectorTypesAltivec - invalid input types"); + + bool isSrcTyAltivec = false; + bool isDestTyAltivec = false; + + if (SrcTy->isVectorType()) { + VectorType::VectorKind SrcVecKind = + SrcTy->castAs()->getVectorKind(); + isSrcTyAltivec = (SrcVecKind == VectorType::AltiVecVector); + } + if (DestTy->isVectorType()) { + VectorType::VectorKind DestVecKind = + DestTy->castAs()->getVectorKind(); + isDestTyAltivec = (DestVecKind == VectorType::AltiVecVector); + } + + return (isSrcTyAltivec || isDestTyAltivec); +} + +// This returns true if both vectors have the same element type. +bool Sema::areVectorTypesSameElmType(QualType SrcTy, QualType DestTy) { + assert((DestTy->isVectorType() || SrcTy->isVectorType()) && + "areVectorTypesSameElmType -invalid input types"); + + uint64_t SrcLen, DestLen; + QualType SrcEltTy, DestEltTy; + if (!breakDownVectorType(SrcTy, SrcLen, SrcEltTy)) + return false; + if (!breakDownVectorType(DestTy, DestLen, DestEltTy)) + return false; + + return (SrcEltTy == DestEltTy); +} + /// Are the two types lax-compatible vector types? That is, given /// that one of them is a vector, do they have equal storage sizes, /// where the storage size is the number of elements times the element @@ -7758,9 +7795,9 @@ case LangOptions::LaxVectorConversionKind::All: break; - } + } - return areLaxCompatibleVectorTypes(srcTy, destTy); + return areLaxCompatibleVectorTypes(srcTy, destTy); } bool Sema::CheckMatrixCast(SourceRange R, QualType DestTy, QualType SrcTy, @@ -9531,6 +9568,10 @@ // vectors, the total size only needs to be the same. This is a bitcast; // no bits are changed but the result type is different. if (isLaxVectorConversion(RHSType, LHSType)) { + if (areAnyVectorTypesAltivec(RHSType, LHSType) && + !areVectorTypesSameElmType(RHSType, LHSType)) + Diag(RHS.get()->getExprLoc(), diag::warn_deprecated_lax_vec_conv_all) + << RHSType << LHSType; Kind = CK_BitCast; return IncompatibleVectors; } @@ -9544,6 +9585,9 @@ const VectorType *VecType = RHSType->getAs(); if (VecType && VecType->getNumElements() == 1 && isLaxVectorConversion(RHSType, LHSType)) { + if (VecType->getVectorKind() == VectorType::AltiVecVector) + Diag(RHS.get()->getExprLoc(), diag::warn_deprecated_lax_vec_conv_all) + << RHSType << LHSType; ExprResult *VecExpr = &RHS; *VecExpr = ImpCastExprToType(VecExpr->get(), LHSType, CK_BitCast); Kind = CK_BitCast; @@ -10476,6 +10520,9 @@ QualType OtherType = LHSVecType ? RHSType : LHSType; ExprResult *OtherExpr = LHSVecType ? &RHS : &LHS; if (isLaxVectorConversion(OtherType, VecType)) { + if (areAnyVectorTypesAltivec(RHSType, LHSType) && + !areVectorTypesSameElmType(RHSType, LHSType)) + Diag(Loc, diag::warn_deprecated_lax_vec_conv_all) << RHSType << LHSType; // If we're allowing lax vector conversions, only the total (data) size // needs to be the same. For non compound assignment, if one of the types is // scalar, the result is always the vector type. diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1617,8 +1617,9 @@ /// /// \param ICK Will be set to the vector conversion kind, if this is a vector /// conversion. -static bool IsVectorConversion(Sema &S, QualType FromType, - QualType ToType, ImplicitConversionKind &ICK) { +static bool IsVectorConversion(Sema &S, QualType FromType, QualType ToType, + ImplicitConversionKind &ICK, Expr *From, + bool InOverloadResolution) { // We need at least one of these types to be a vector type to have a vector // conversion. if (!ToType->isVectorType() && !FromType->isVectorType()) @@ -1660,6 +1661,13 @@ if (S.Context.areCompatibleVectorTypes(FromType, ToType) || (S.isLaxVectorConversion(FromType, ToType) && !ToType->hasAttr(attr::ArmMveStrictPolymorphism))) { + if (S.isLaxVectorConversion(FromType, ToType) && + S.areAnyVectorTypesAltivec(FromType, ToType) && + !S.areVectorTypesSameElmType(FromType, ToType) && + !InOverloadResolution) { + S.Diag(From->getBeginLoc(), diag::warn_deprecated_lax_vec_conv_all) + << FromType << ToType; + } ICK = ICK_Vector_Conversion; return true; } @@ -1908,7 +1916,8 @@ InOverloadResolution, FromType)) { // Pointer to member conversions (4.11). SCS.Second = ICK_Pointer_Member; - } else if (IsVectorConversion(S, FromType, ToType, SecondICK)) { + } else if (IsVectorConversion(S, FromType, ToType, SecondICK, From, + InOverloadResolution)) { SCS.Second = SecondICK; FromType = ToType.getUnqualifiedType(); } else if (!S.getLangOpts().CPlusPlus && diff --git a/clang/test/Parser/cxx-altivec.cpp b/clang/test/Parser/cxx-altivec.cpp --- a/clang/test/Parser/cxx-altivec.cpp +++ b/clang/test/Parser/cxx-altivec.cpp @@ -1,10 +1,10 @@ -// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -target-feature +altivec -fsyntax-only -verify=expected,novsx -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -target-feature +altivec -target-feature +vsx -fsyntax-only -verify=expected,nonaix -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -target-feature +altivec -fsyntax-only -verify=expected,novsx -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -target-feature +vsx -target-cpu pwr7 -fsyntax-only -verify=expected,nonaix -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -target-feature -vsx -target-cpu pwr7 -fsyntax-only -verify=expected,novsx -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc-ibm-aix -target-feature +altivec -fsyntax-only -verify=expected,aix -std=c++11 %s -// RUN: %clang_cc1 -triple=powerpc64-ibm-aix -target-feature +altivec -fsyntax-only -verify=expected,aix -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc-apple-darwin8 -Wno-deprecate-lax-vec-conv-all -target-feature +altivec -fsyntax-only -verify=expected,novsx -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -Wno-deprecate-lax-vec-conv-all -target-feature +altivec -target-feature +vsx -fsyntax-only -verify=expected,nonaix -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -Wno-deprecate-lax-vec-conv-all -target-feature +altivec -fsyntax-only -verify=expected,novsx -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64-unknown-linux-gnu -Wno-deprecate-lax-vec-conv-all -target-feature +vsx -target-cpu pwr7 -fsyntax-only -verify=expected,nonaix -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64le-unknown-linux-gnu -Wno-deprecate-lax-vec-conv-all -target-feature -vsx -target-cpu pwr7 -fsyntax-only -verify=expected,novsx -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc-ibm-aix -Wno-deprecate-lax-vec-conv-all -target-feature +altivec -fsyntax-only -verify=expected,aix -std=c++11 %s +// RUN: %clang_cc1 -triple=powerpc64-ibm-aix -Wno-deprecate-lax-vec-conv-all -target-feature +altivec -fsyntax-only -verify=expected,aix -std=c++11 %s #include __vector char vv_c;