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; | 
