diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 52 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 24 |
2 files changed, 55 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 32bf6e01c9f..41c7613c74a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -309,6 +309,10 @@ Sema::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (CheckARMBuiltinFunctionCall(BuiltinID, TheCall)) return ExprError(); break; + case llvm::Triple::arm64: + if (CheckARM64BuiltinFunctionCall(BuiltinID, TheCall)) + return ExprError(); + break; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall)) @@ -369,7 +373,7 @@ static unsigned RFT(unsigned t, bool shift = false, bool ForceQuad = false) { /// the vector type specified by the NeonTypeFlags. This is used to check /// the pointer arguments for Neon load/store intrinsics. static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, - bool IsAArch64) { + bool IsPolyUnsigned, bool IsInt64Long) { switch (Flags.getEltType()) { case NeonTypeFlags::Int8: return Flags.isUnsigned() ? Context.UnsignedCharTy : Context.SignedCharTy; @@ -378,15 +382,15 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, case NeonTypeFlags::Int32: return Flags.isUnsigned() ? Context.UnsignedIntTy : Context.IntTy; case NeonTypeFlags::Int64: - if (IsAArch64) + if (IsInt64Long) return Flags.isUnsigned() ? Context.UnsignedLongTy : Context.LongTy; else return Flags.isUnsigned() ? Context.UnsignedLongLongTy : Context.LongLongTy; case NeonTypeFlags::Poly8: - return IsAArch64 ? Context.UnsignedCharTy : Context.SignedCharTy; + return IsPolyUnsigned ? Context.UnsignedCharTy : Context.SignedCharTy; case NeonTypeFlags::Poly16: - return IsAArch64 ? Context.UnsignedShortTy : Context.ShortTy; + return IsPolyUnsigned ? Context.UnsignedShortTy : Context.ShortTy; case NeonTypeFlags::Poly64: return Context.UnsignedLongTy; case NeonTypeFlags::Poly128: @@ -434,9 +438,13 @@ bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); QualType RHSTy = RHS.get()->getType(); - bool IsAArch64 = - Context.getTargetInfo().getTriple().getArch() == llvm::Triple::aarch64; - QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, IsAArch64); + llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch(); + bool IsPolyUnsigned = + Arch == llvm::Triple::aarch64 || Arch == llvm::Triple::arm64; + bool IsInt64Long = + Context.getTargetInfo().getInt64Type() == TargetInfo::SignedLong; + QualType EltTy = + getNeonEltType(NeonTypeFlags(TV), Context, IsPolyUnsigned, IsInt64Long); if (HasConstPtr) EltTy = EltTy.withConst(); QualType LHSTy = Context.getPointerType(EltTy); @@ -487,11 +495,15 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, return false; } -bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { +bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, + unsigned MaxWidth) { assert((BuiltinID == ARM::BI__builtin_arm_ldrex || - BuiltinID == ARM::BI__builtin_arm_strex) && + BuiltinID == ARM::BI__builtin_arm_strex || + BuiltinID == ARM64::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_strex) && "unexpected ARM builtin"); - bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex; + bool IsLdrex = BuiltinID == ARM::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_ldrex; DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); @@ -552,7 +564,8 @@ bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { } // But ARM doesn't have instructions to deal with 128-bit versions. - if (Context.getTypeSize(ValType) > 64) { + if (Context.getTypeSize(ValType) > MaxWidth) { + assert(MaxWidth == 64 && "Diagnostic unexpectedly inaccurate"); Diag(DRE->getLocStart(), diag::err_atomic_exclusive_builtin_pointer_size) << PointerArg->getType() << PointerArg->getSourceRange(); return true; @@ -598,7 +611,7 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == ARM::BI__builtin_arm_ldrex || BuiltinID == ARM::BI__builtin_arm_strex) { - return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall); + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 64); } if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) @@ -636,6 +649,21 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return false; } +bool Sema::CheckARM64BuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + llvm::APSInt Result; + + if (BuiltinID == ARM64::BI__builtin_arm_ldrex || + BuiltinID == ARM64::BI__builtin_arm_strex) { + return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall, 128); + } + + if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + + return false; +} + bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { unsigned i = 0, l = 0, u = 0; switch (BuiltinID) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 035778bbc1d..e273cb6e364 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -4720,14 +4720,20 @@ static void HandleExtVectorTypeAttr(QualType &CurType, } static bool isPermittedNeonBaseType(QualType &Ty, - VectorType::VectorKind VecKind, - bool IsAArch64) { + VectorType::VectorKind VecKind, Sema &S) { const BuiltinType *BTy = Ty->getAs<BuiltinType>(); if (!BTy) return false; + llvm::Triple Triple = S.Context.getTargetInfo().getTriple(); + + // Signed poly is mathematically wrong, but has been baked into some ABIs by + // now. + bool IsPolyUnsigned = Triple.getArch() == llvm::Triple::aarch64 || + Triple.getArch() == llvm::Triple::aarch64_be || + Triple.getArch() == llvm::Triple::arm64; if (VecKind == VectorType::NeonPolyVector) { - if (IsAArch64) { + if (IsPolyUnsigned) { // AArch64 polynomial vectors are unsigned and support poly64. return BTy->getKind() == BuiltinType::UChar || BTy->getKind() == BuiltinType::UShort || @@ -4742,7 +4748,11 @@ static bool isPermittedNeonBaseType(QualType &Ty, // Non-polynomial vector types: the usual suspects are allowed, as well as // float64_t on AArch64. - if (IsAArch64 && BTy->getKind() == BuiltinType::Double) + bool Is64Bit = Triple.getArch() == llvm::Triple::aarch64 || + Triple.getArch() == llvm::Triple::aarch64_be || + Triple.getArch() == llvm::Triple::arm64; + + if (Is64Bit && BTy->getKind() == BuiltinType::Double) return true; return BTy->getKind() == BuiltinType::SChar || @@ -4794,11 +4804,7 @@ static void HandleNeonVectorTypeAttr(QualType& CurType, return; } // Only certain element types are supported for Neon vectors. - llvm::Triple::ArchType Arch = - S.Context.getTargetInfo().getTriple().getArch(); - if (!isPermittedNeonBaseType(CurType, VecKind, - (Arch == llvm::Triple::aarch64) || - (Arch == llvm::Triple::aarch64_be))) { + if (!isPermittedNeonBaseType(CurType, VecKind, S)) { S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) << CurType; Attr.setInvalid(); return; |