diff options
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 210 |
1 files changed, 193 insertions, 17 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 3aedb2a8c9bb..81db0d3d00a7 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -244,7 +244,7 @@ static bool SemaBuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, // Scopes aren't available during instantiation. Fortunately, builtin // functions cannot be template args so they cannot be formed through template // instantiation. Therefore checking once during the parse is sufficient. - if (!SemaRef.ActiveTemplateInstantiations.empty()) + if (SemaRef.inTemplateInstantiation()) return false; Scope *S = SemaRef.getCurScope(); @@ -315,7 +315,7 @@ static bool SemaOpenCLBuiltinKernelWorkGroupSize(Sema &S, CallExpr *TheCall) { return checkOpenCLBlockArgs(S, BlockArg); } -/// Diagnose integer type and any valid implicit convertion to it. +/// Diagnose integer type and any valid implicit conversion to it. static bool checkOpenCLEnqueueIntType(Sema &S, Expr *E, const QualType &IntType); @@ -408,10 +408,10 @@ static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) { } // Third argument is always an ndrange_t type. - if (!Arg2->getType()->isNDRangeT()) { + if (Arg2->getType().getAsString() != "ndrange_t") { S.Diag(TheCall->getArg(2)->getLocStart(), diag::err_opencl_enqueue_kernel_expected_type) - << S.Context.OCLNDRangeTy; + << "'ndrange_t'"; return true; } @@ -1619,32 +1619,28 @@ bool Sema::CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case Mips::BI__builtin_msa_copy_u_b: case Mips::BI__builtin_msa_insve_b: case Mips::BI__builtin_msa_splati_b: i = 1; l = 0; u = 15; break; - case Mips::BI__builtin_msa_sld_b: case Mips::BI__builtin_msa_sldi_b: i = 2; l = 0; u = 15; break; // These intrinsics take an unsigned 3 bit immediate. case Mips::BI__builtin_msa_copy_s_h: case Mips::BI__builtin_msa_copy_u_h: case Mips::BI__builtin_msa_insve_h: case Mips::BI__builtin_msa_splati_h: i = 1; l = 0; u = 7; break; - case Mips::BI__builtin_msa_sld_h: case Mips::BI__builtin_msa_sldi_h: i = 2; l = 0; u = 7; break; // These intrinsics take an unsigned 2 bit immediate. case Mips::BI__builtin_msa_copy_s_w: case Mips::BI__builtin_msa_copy_u_w: case Mips::BI__builtin_msa_insve_w: case Mips::BI__builtin_msa_splati_w: i = 1; l = 0; u = 3; break; - case Mips::BI__builtin_msa_sld_w: case Mips::BI__builtin_msa_sldi_w: i = 2; l = 0; u = 3; break; // These intrinsics take an unsigned 1 bit immediate. case Mips::BI__builtin_msa_copy_s_d: case Mips::BI__builtin_msa_copy_u_d: case Mips::BI__builtin_msa_insve_d: case Mips::BI__builtin_msa_splati_d: i = 1; l = 0; u = 1; break; - case Mips::BI__builtin_msa_sld_d: case Mips::BI__builtin_msa_sldi_d: i = 2; l = 0; u = 1; break; // Memory offsets and immediate loads. // These intrinsics take a signed 10 bit immediate. - case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 127; break; + case Mips::BI__builtin_msa_ldi_b: i = 0; l = -128; u = 255; break; case Mips::BI__builtin_msa_ldi_h: case Mips::BI__builtin_msa_ldi_w: case Mips::BI__builtin_msa_ldi_d: i = 0; l = -512; u = 511; break; @@ -1990,6 +1986,109 @@ bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) { << Arg->getSourceRange(); } +// Check if the gather/scatter scale is legal. +bool Sema::CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, + CallExpr *TheCall) { + unsigned ArgNum = 0; + switch (BuiltinID) { + default: + return false; + case X86::BI__builtin_ia32_gatherpfdpd: + case X86::BI__builtin_ia32_gatherpfdps: + case X86::BI__builtin_ia32_gatherpfqpd: + case X86::BI__builtin_ia32_gatherpfqps: + case X86::BI__builtin_ia32_scatterpfdpd: + case X86::BI__builtin_ia32_scatterpfdps: + case X86::BI__builtin_ia32_scatterpfqpd: + case X86::BI__builtin_ia32_scatterpfqps: + ArgNum = 3; + break; + case X86::BI__builtin_ia32_gatherd_pd: + case X86::BI__builtin_ia32_gatherd_pd256: + case X86::BI__builtin_ia32_gatherq_pd: + case X86::BI__builtin_ia32_gatherq_pd256: + case X86::BI__builtin_ia32_gatherd_ps: + case X86::BI__builtin_ia32_gatherd_ps256: + case X86::BI__builtin_ia32_gatherq_ps: + case X86::BI__builtin_ia32_gatherq_ps256: + case X86::BI__builtin_ia32_gatherd_q: + case X86::BI__builtin_ia32_gatherd_q256: + case X86::BI__builtin_ia32_gatherq_q: + case X86::BI__builtin_ia32_gatherq_q256: + case X86::BI__builtin_ia32_gatherd_d: + case X86::BI__builtin_ia32_gatherd_d256: + case X86::BI__builtin_ia32_gatherq_d: + case X86::BI__builtin_ia32_gatherq_d256: + case X86::BI__builtin_ia32_gather3div2df: + case X86::BI__builtin_ia32_gather3div2di: + case X86::BI__builtin_ia32_gather3div4df: + case X86::BI__builtin_ia32_gather3div4di: + case X86::BI__builtin_ia32_gather3div4sf: + case X86::BI__builtin_ia32_gather3div4si: + case X86::BI__builtin_ia32_gather3div8sf: + case X86::BI__builtin_ia32_gather3div8si: + case X86::BI__builtin_ia32_gather3siv2df: + case X86::BI__builtin_ia32_gather3siv2di: + case X86::BI__builtin_ia32_gather3siv4df: + case X86::BI__builtin_ia32_gather3siv4di: + case X86::BI__builtin_ia32_gather3siv4sf: + case X86::BI__builtin_ia32_gather3siv4si: + case X86::BI__builtin_ia32_gather3siv8sf: + case X86::BI__builtin_ia32_gather3siv8si: + case X86::BI__builtin_ia32_gathersiv8df: + case X86::BI__builtin_ia32_gathersiv16sf: + case X86::BI__builtin_ia32_gatherdiv8df: + case X86::BI__builtin_ia32_gatherdiv16sf: + case X86::BI__builtin_ia32_gathersiv8di: + case X86::BI__builtin_ia32_gathersiv16si: + case X86::BI__builtin_ia32_gatherdiv8di: + case X86::BI__builtin_ia32_gatherdiv16si: + case X86::BI__builtin_ia32_scatterdiv2df: + case X86::BI__builtin_ia32_scatterdiv2di: + case X86::BI__builtin_ia32_scatterdiv4df: + case X86::BI__builtin_ia32_scatterdiv4di: + case X86::BI__builtin_ia32_scatterdiv4sf: + case X86::BI__builtin_ia32_scatterdiv4si: + case X86::BI__builtin_ia32_scatterdiv8sf: + case X86::BI__builtin_ia32_scatterdiv8si: + case X86::BI__builtin_ia32_scattersiv2df: + case X86::BI__builtin_ia32_scattersiv2di: + case X86::BI__builtin_ia32_scattersiv4df: + case X86::BI__builtin_ia32_scattersiv4di: + case X86::BI__builtin_ia32_scattersiv4sf: + case X86::BI__builtin_ia32_scattersiv4si: + case X86::BI__builtin_ia32_scattersiv8sf: + case X86::BI__builtin_ia32_scattersiv8si: + case X86::BI__builtin_ia32_scattersiv8df: + case X86::BI__builtin_ia32_scattersiv16sf: + case X86::BI__builtin_ia32_scatterdiv8df: + case X86::BI__builtin_ia32_scatterdiv16sf: + case X86::BI__builtin_ia32_scattersiv8di: + case X86::BI__builtin_ia32_scattersiv16si: + case X86::BI__builtin_ia32_scatterdiv8di: + case X86::BI__builtin_ia32_scatterdiv16si: + ArgNum = 4; + break; + } + + llvm::APSInt Result; + + // We can't check the value of a dependent argument. + Expr *Arg = TheCall->getArg(ArgNum); + if (Arg->isTypeDependent() || Arg->isValueDependent()) + return false; + + // Check constant-ness first. + if (SemaBuiltinConstantArg(TheCall, ArgNum, Result)) + return true; + + if (Result == 1 || Result == 2 || Result == 4 || Result == 8) + return false; + + return Diag(TheCall->getLocStart(), diag::err_x86_builtin_invalid_scale) + << Arg->getSourceRange(); +} + bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (BuiltinID == X86::BI__builtin_cpu_supports) return SemaBuiltinCpuSupports(*this, TheCall); @@ -2001,6 +2100,10 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall)) return true; + // If the intrinsic has a gather/scatter scale immediate make sure its valid. + if (CheckX86BuiltinGatherScatterScale(BuiltinID, TheCall)) + return true; + // For intrinsics which take an immediate value as part of the instruction, // range check them here. int i = 0, l = 0, u = 0; @@ -2197,6 +2300,16 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case X86::BI__builtin_ia32_pternlogq256_maskz: i = 3; l = 0; u = 255; break; + case X86::BI__builtin_ia32_gatherpfdpd: + case X86::BI__builtin_ia32_gatherpfdps: + case X86::BI__builtin_ia32_gatherpfqpd: + case X86::BI__builtin_ia32_gatherpfqps: + case X86::BI__builtin_ia32_scatterpfdpd: + case X86::BI__builtin_ia32_scatterpfdps: + case X86::BI__builtin_ia32_scatterpfqpd: + case X86::BI__builtin_ia32_scatterpfqps: + i = 4; l = 2; u = 3; + break; case X86::BI__builtin_ia32_pcmpestrm128: case X86::BI__builtin_ia32_pcmpestri128: case X86::BI__builtin_ia32_pcmpestria128: @@ -6782,7 +6895,7 @@ void Sema::CheckMaxUnsignedZero(const CallExpr *Call, if (!Call || !FDecl) return; // Ignore template specializations and macros. - if (!ActiveTemplateInstantiations.empty()) return; + if (inTemplateInstantiation()) return; if (Call->getExprLoc().isMacroID()) return; // Only care about the one template argument, two function parameter std::max @@ -7340,7 +7453,7 @@ CheckReturnStackAddr(Sema &S, Expr *RetValExp, QualType lhsType, if (!stackE) return; // Nothing suspicious was found. - // Parameters are initalized in the calling scope, so taking the address + // Parameters are initialized in the calling scope, so taking the address // of a parameter reference doesn't need a warning. for (auto *DRE : refVars) if (isa<ParmVarDecl>(DRE->getDecl())) @@ -8235,7 +8348,7 @@ bool HasEnumType(Expr *E) { void CheckTrivialUnsignedComparison(Sema &S, BinaryOperator *E) { // Disable warning in template instantiations. - if (!S.ActiveTemplateInstantiations.empty()) + if (S.inTemplateInstantiation()) return; BinaryOperatorKind op = E->getOpcode(); @@ -8265,7 +8378,7 @@ void DiagnoseOutOfRangeComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant) { // Disable warning in template instantiations. - if (!S.ActiveTemplateInstantiations.empty()) + if (S.inTemplateInstantiation()) return; // TODO: Investigate using GetExprRange() to get tighter bounds @@ -8616,13 +8729,66 @@ bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, return false; Expr *OriginalInit = Init->IgnoreParenImpCasts(); + unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); llvm::APSInt Value; - if (!OriginalInit->EvaluateAsInt(Value, S.Context, Expr::SE_AllowSideEffects)) + if (!OriginalInit->EvaluateAsInt(Value, S.Context, + Expr::SE_AllowSideEffects)) { + // The RHS is not constant. If the RHS has an enum type, make sure the + // bitfield is wide enough to hold all the values of the enum without + // truncation. + if (const auto *EnumTy = OriginalInit->getType()->getAs<EnumType>()) { + EnumDecl *ED = EnumTy->getDecl(); + bool SignedBitfield = BitfieldType->isSignedIntegerType(); + + // Enum types are implicitly signed on Windows, so check if there are any + // negative enumerators to see if the enum was intended to be signed or + // not. + bool SignedEnum = ED->getNumNegativeBits() > 0; + + // Check for surprising sign changes when assigning enum values to a + // bitfield of different signedness. If the bitfield is signed and we + // have exactly the right number of bits to store this unsigned enum, + // suggest changing the enum to an unsigned type. This typically happens + // on Windows where unfixed enums always use an underlying type of 'int'. + unsigned DiagID = 0; + if (SignedEnum && !SignedBitfield) { + DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum; + } else if (SignedBitfield && !SignedEnum && + ED->getNumPositiveBits() == FieldWidth) { + DiagID = diag::warn_signed_bitfield_enum_conversion; + } + + if (DiagID) { + S.Diag(InitLoc, DiagID) << Bitfield << ED; + TypeSourceInfo *TSI = Bitfield->getTypeSourceInfo(); + SourceRange TypeRange = + TSI ? TSI->getTypeLoc().getSourceRange() : SourceRange(); + S.Diag(Bitfield->getTypeSpecStartLoc(), diag::note_change_bitfield_sign) + << SignedEnum << TypeRange; + } + + // Compute the required bitwidth. If the enum has negative values, we need + // one more bit than the normal number of positive bits to represent the + // sign bit. + unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1, + ED->getNumNegativeBits()) + : ED->getNumPositiveBits(); + + // Check the bitwidth. + if (BitsNeeded > FieldWidth) { + Expr *WidthExpr = Bitfield->getBitWidth(); + S.Diag(InitLoc, diag::warn_bitfield_too_small_for_enum) + << Bitfield << ED; + S.Diag(WidthExpr->getExprLoc(), diag::note_widen_bitfield) + << BitsNeeded << ED << WidthExpr->getSourceRange(); + } + } + return false; + } unsigned OriginalWidth = Value.getBitWidth(); - unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context); if (!Value.isSigned() || Value.isNegative()) if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit)) @@ -8703,7 +8869,7 @@ void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext) { const bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool); - const bool PruneWarnings = !S.ActiveTemplateInstantiations.empty(); + const bool PruneWarnings = S.inTemplateInstantiation(); Expr *InnerE = E->IgnoreParenImpCasts(); // We also want to warn on, e.g., "int i = -1.234" @@ -10609,6 +10775,12 @@ void Sema::CheckArrayAccess(const Expr *expr) { CheckArrayAccess(rhs); return; } + case Stmt::CXXOperatorCallExprClass: { + const auto *OCE = cast<CXXOperatorCallExpr>(expr); + for (const auto *Arg : OCE->arguments()) + CheckArrayAccess(Arg); + return; + } default: return; } @@ -11314,7 +11486,7 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, if (Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc)) return; - if (!ActiveTemplateInstantiations.empty()) + if (inTemplateInstantiation()) return; // Strip parens and casts away. @@ -11839,6 +12011,10 @@ void Sema::RefersToMemberWithReducedAlignment( if (!ME) return; + // No need to check expressions with an __unaligned-qualified type. + if (E->getType().getQualifiers().hasUnaligned()) + return; + // For a chain of MemberExpr like "a.b.c.d" this list // will keep FieldDecl's like [d, c, b]. SmallVector<FieldDecl *, 4> ReverseMemberChain; |