diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp | 612 | 
1 files changed, 481 insertions, 131 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp index f9f82cdeef43..dca81d1d275f 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaChecking.cpp @@ -191,7 +191,7 @@ static bool SemaBuiltinAddressof(Sema &S, CallExpr *TheCall) {    return false;  } -/// Check the number of arguments, and set the result type to +/// Check the number of arguments and set the result type to  /// the argument type.  static bool SemaBuiltinPreserveAI(Sema &S, CallExpr *TheCall) {    if (checkArgCount(S, TheCall, 1)) @@ -484,7 +484,7 @@ static bool checkOpenCLBlockArgs(Sema &S, Expr *BlockArg) {    const BlockPointerType *BPT =        cast<BlockPointerType>(BlockArg->getType().getCanonicalType());    ArrayRef<QualType> Params = -      BPT->getPointeeType()->getAs<FunctionProtoType>()->getParamTypes(); +      BPT->getPointeeType()->castAs<FunctionProtoType>()->getParamTypes();    unsigned ArgCounter = 0;    bool IllegalParams = false;    // Iterate through the block parameters until either one is found that is not @@ -583,7 +583,7 @@ static bool checkOpenCLEnqueueVariadicArgs(Sema &S, CallExpr *TheCall,    const BlockPointerType *BPT =        cast<BlockPointerType>(BlockArg->getType().getCanonicalType());    unsigned NumBlockParams = -      BPT->getPointeeType()->getAs<FunctionProtoType>()->getNumParams(); +      BPT->getPointeeType()->castAs<FunctionProtoType>()->getNumParams();    unsigned TotalNumArgs = TheCall->getNumArgs();    // For each argument passed to the block, a corresponding uint needs to @@ -629,7 +629,9 @@ static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) {    unsigned NumArgs = TheCall->getNumArgs();    if (NumArgs < 4) { -    S.Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args); +    S.Diag(TheCall->getBeginLoc(), +           diag::err_typecheck_call_too_few_args_at_least) +        << 0 << 4 << NumArgs;      return true;    } @@ -674,7 +676,7 @@ static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) {      // we have a block type, check the prototype      const BlockPointerType *BPT =          cast<BlockPointerType>(Arg3->getType().getCanonicalType()); -    if (BPT->getPointeeType()->getAs<FunctionProtoType>()->getNumParams() > 0) { +    if (BPT->getPointeeType()->castAs<FunctionProtoType>()->getNumParams() > 0) {        S.Diag(Arg3->getBeginLoc(),               diag::err_opencl_enqueue_kernel_blocks_no_args);        return true; @@ -1179,6 +1181,10 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,    case Builtin::BI__builtin_alloca_with_align:      if (SemaBuiltinAllocaWithAlign(TheCall))        return ExprError(); +    LLVM_FALLTHROUGH; +  case Builtin::BI__builtin_alloca: +    Diag(TheCall->getBeginLoc(), diag::warn_alloca) +        << TheCall->getDirectCallee();      break;    case Builtin::BI__assume:    case Builtin::BI__builtin_assume: @@ -1534,6 +1540,11 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,          if (CheckAArch64BuiltinFunctionCall(BuiltinID, TheCall))            return ExprError();          break; +      case llvm::Triple::bpfeb: +      case llvm::Triple::bpfel: +        if (CheckBPFBuiltinFunctionCall(BuiltinID, TheCall)) +          return ExprError(); +        break;        case llvm::Triple::hexagon:          if (CheckHexagonBuiltinFunctionCall(BuiltinID, TheCall))            return ExprError(); @@ -1928,11 +1939,46 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,    case AArch64::BI__builtin_arm_dmb:    case AArch64::BI__builtin_arm_dsb:    case AArch64::BI__builtin_arm_isb: l = 0; u = 15; break; +  case AArch64::BI__builtin_arm_tcancel: l = 0; u = 65535; break;    }    return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);  } +bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID, +                                       CallExpr *TheCall) { +  assert(BuiltinID == BPF::BI__builtin_preserve_field_info && +         "unexpected ARM builtin"); + +  if (checkArgCount(*this, TheCall, 2)) +    return true; + +  // The first argument needs to be a record field access. +  // If it is an array element access, we delay decision +  // to BPF backend to check whether the access is a +  // field access or not. +  Expr *Arg = TheCall->getArg(0); +  if (Arg->getType()->getAsPlaceholderType() || +      (Arg->IgnoreParens()->getObjectKind() != OK_BitField && +       !dyn_cast<MemberExpr>(Arg->IgnoreParens()) && +       !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()))) { +    Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_field) +        << 1 << Arg->getSourceRange(); +    return true; +  } + +  // The second argument needs to be a constant int +  llvm::APSInt Value; +  if (!TheCall->getArg(1)->isIntegerConstantExpr(Value, Context)) { +    Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) +        << 2 << Arg->getSourceRange(); +    return true; +  } + +  TheCall->setType(Context.UnsignedIntTy); +  return false; +} +  bool Sema::CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall) {    struct BuiltinAndString {      unsigned BuiltinID; @@ -3213,6 +3259,8 @@ bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case PPC::BI__builtin_altivec_crypto_vshasigmad:      return SemaBuiltinConstantArgRange(TheCall, 1, 0, 1) ||             SemaBuiltinConstantArgRange(TheCall, 2, 0, 15); +  case PPC::BI__builtin_altivec_dss: +    return SemaBuiltinConstantArgRange(TheCall, 0, 0, 3);    case PPC::BI__builtin_tbegin:    case PPC::BI__builtin_tend: i = 0; l = 0; u = 1; break;    case PPC::BI__builtin_tsr: i = 0; l = 0; u = 7; break; @@ -3222,6 +3270,11 @@ bool Sema::CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {    case PPC::BI__builtin_tabortdci:      return SemaBuiltinConstantArgRange(TheCall, 0, 0, 31) ||             SemaBuiltinConstantArgRange(TheCall, 2, 0, 31); +  case PPC::BI__builtin_altivec_dst: +  case PPC::BI__builtin_altivec_dstt: +  case PPC::BI__builtin_altivec_dstst: +  case PPC::BI__builtin_altivec_dststt: +    return SemaBuiltinConstantArgRange(TheCall, 2, 0, 3);    case PPC::BI__builtin_vsx_xxpermdi:    case PPC::BI__builtin_vsx_xxsldwi:      return SemaBuiltinVSX(TheCall); @@ -3532,9 +3585,11 @@ bool Sema::CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall) {    // Make sure rounding mode is either ROUND_CUR_DIRECTION or ROUND_NO_EXC bit    // is set. If the intrinsic has rounding control(bits 1:0), make sure its only -  // combined with ROUND_NO_EXC. +  // combined with ROUND_NO_EXC. If the intrinsic does not have rounding +  // control, allow ROUND_NO_EXC and ROUND_CUR_DIRECTION together.    if (Result == 4/*ROUND_CUR_DIRECTION*/ ||        Result == 8/*ROUND_NO_EXC*/ || +      (!HasRC && Result == 12/*ROUND_CUR_DIRECTION|ROUND_NO_EXC*/) ||        (HasRC && Result.getZExtValue() >= 8 && Result.getZExtValue() <= 11))      return false; @@ -4449,7 +4504,16 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,                                           AtomicExpr::AtomicOp Op) {    CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());    DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts()); +  MultiExprArg Args{TheCall->getArgs(), TheCall->getNumArgs()}; +  return BuildAtomicExpr({TheCall->getBeginLoc(), TheCall->getEndLoc()}, +                         DRE->getSourceRange(), TheCall->getRParenLoc(), Args, +                         Op); +} +ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, +                                 SourceLocation RParenLoc, MultiExprArg Args, +                                 AtomicExpr::AtomicOp Op, +                                 AtomicArgumentOrder ArgOrder) {    // All the non-OpenCL operations take one of the following forms.    // The OpenCL operations take the __c11 forms with one extra argument for    // synchronization scope. @@ -4596,21 +4660,21 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init)      ++AdjustedNumArgs;    // Check we have the right number of arguments. -  if (TheCall->getNumArgs() < AdjustedNumArgs) { -    Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) -        << 0 << AdjustedNumArgs << TheCall->getNumArgs() -        << TheCall->getCallee()->getSourceRange(); +  if (Args.size() < AdjustedNumArgs) { +    Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args) +        << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size()) +        << ExprRange;      return ExprError(); -  } else if (TheCall->getNumArgs() > AdjustedNumArgs) { -    Diag(TheCall->getArg(AdjustedNumArgs)->getBeginLoc(), +  } else if (Args.size() > AdjustedNumArgs) { +    Diag(Args[AdjustedNumArgs]->getBeginLoc(),           diag::err_typecheck_call_too_many_args) -        << 0 << AdjustedNumArgs << TheCall->getNumArgs() -        << TheCall->getCallee()->getSourceRange(); +        << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size()) +        << ExprRange;      return ExprError();    }    // Inspect the first argument of the atomic operation. -  Expr *Ptr = TheCall->getArg(0); +  Expr *Ptr = Args[0];    ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr);    if (ConvertedPtr.isInvalid())      return ExprError(); @@ -4618,7 +4682,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    Ptr = ConvertedPtr.get();    const PointerType *pointerType = Ptr->getType()->getAs<PointerType>();    if (!pointerType) { -    Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer) +    Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)          << Ptr->getType() << Ptr->getSourceRange();      return ExprError();    } @@ -4628,21 +4692,21 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    QualType ValType = AtomTy; // 'C'    if (IsC11) {      if (!AtomTy->isAtomicType()) { -      Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic) +      Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic)            << Ptr->getType() << Ptr->getSourceRange();        return ExprError();      }      if ((Form != Load && Form != LoadCopy && AtomTy.isConstQualified()) ||          AtomTy.getAddressSpace() == LangAS::opencl_constant) { -      Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_non_const_atomic) +      Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_non_const_atomic)            << (AtomTy.isConstQualified() ? 0 : 1) << Ptr->getType()            << Ptr->getSourceRange();        return ExprError();      } -    ValType = AtomTy->getAs<AtomicType>()->getValueType(); +    ValType = AtomTy->castAs<AtomicType>()->getValueType();    } else if (Form != Load && Form != LoadCopy) {      if (ValType.isConstQualified()) { -      Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_non_const_pointer) +      Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_non_const_pointer)            << Ptr->getType() << Ptr->getSourceRange();        return ExprError();      } @@ -4653,7 +4717,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,      // gcc does not enforce these rules for GNU atomics, but we do so for sanity.      if (IsAddSub && !ValType->isIntegerType()          && !ValType->isPointerType()) { -      Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic_int_or_ptr) +      Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)            << IsC11 << Ptr->getType() << Ptr->getSourceRange();        return ExprError();      } @@ -4661,12 +4725,12 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,        const BuiltinType *BT = ValType->getAs<BuiltinType>();        if (!BT || (BT->getKind() != BuiltinType::Int &&                    BT->getKind() != BuiltinType::UInt)) { -        Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_int32_or_ptr); +        Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_int32_or_ptr);          return ExprError();        }      }      if (!IsAddSub && !IsMinMax && !ValType->isIntegerType()) { -      Diag(DRE->getBeginLoc(), diag::err_atomic_op_bitwise_needs_atomic_int) +      Diag(ExprRange.getBegin(), diag::err_atomic_op_bitwise_needs_atomic_int)            << IsC11 << Ptr->getType() << Ptr->getSourceRange();        return ExprError();      } @@ -4678,7 +4742,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    } else if (IsN && !ValType->isIntegerType() && !ValType->isPointerType()) {      // For __atomic_*_n operations, the value type must be a scalar integral or      // pointer type which is 1, 2, 4, 8 or 16 bytes in length. -    Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic_int_or_ptr) +    Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)          << IsC11 << Ptr->getType() << Ptr->getSourceRange();      return ExprError();    } @@ -4687,7 +4751,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,        !AtomTy->isScalarType()) {      // For GNU atomics, require a trivially-copyable type. This is not part of      // the GNU atomics specification, but we enforce it for sanity. -    Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_trivial_copy) +    Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_trivial_copy)          << Ptr->getType() << Ptr->getSourceRange();      return ExprError();    } @@ -4703,7 +4767,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    case Qualifiers::OCL_Autoreleasing:      // FIXME: Can this happen? By this point, ValType should be known      // to be trivially copyable. -    Diag(DRE->getBeginLoc(), diag::err_arc_atomic_ownership) +    Diag(ExprRange.getBegin(), diag::err_arc_atomic_ownership)          << ValType << Ptr->getSourceRange();      return ExprError();    } @@ -4730,19 +4794,56 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,      IsPassedByAddress = true;    } +  SmallVector<Expr *, 5> APIOrderedArgs; +  if (ArgOrder == Sema::AtomicArgumentOrder::AST) { +    APIOrderedArgs.push_back(Args[0]); +    switch (Form) { +    case Init: +    case Load: +      APIOrderedArgs.push_back(Args[1]); // Val1/Order +      break; +    case LoadCopy: +    case Copy: +    case Arithmetic: +    case Xchg: +      APIOrderedArgs.push_back(Args[2]); // Val1 +      APIOrderedArgs.push_back(Args[1]); // Order +      break; +    case GNUXchg: +      APIOrderedArgs.push_back(Args[2]); // Val1 +      APIOrderedArgs.push_back(Args[3]); // Val2 +      APIOrderedArgs.push_back(Args[1]); // Order +      break; +    case C11CmpXchg: +      APIOrderedArgs.push_back(Args[2]); // Val1 +      APIOrderedArgs.push_back(Args[4]); // Val2 +      APIOrderedArgs.push_back(Args[1]); // Order +      APIOrderedArgs.push_back(Args[3]); // OrderFail +      break; +    case GNUCmpXchg: +      APIOrderedArgs.push_back(Args[2]); // Val1 +      APIOrderedArgs.push_back(Args[4]); // Val2 +      APIOrderedArgs.push_back(Args[5]); // Weak +      APIOrderedArgs.push_back(Args[1]); // Order +      APIOrderedArgs.push_back(Args[3]); // OrderFail +      break; +    } +  } else +    APIOrderedArgs.append(Args.begin(), Args.end()); +    // The first argument's non-CV pointer type is used to deduce the type of    // subsequent arguments, except for:    //  - weak flag (always converted to bool)    //  - memory order (always converted to int)    //  - scope  (always converted to int) -  for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) { +  for (unsigned i = 0; i != APIOrderedArgs.size(); ++i) {      QualType Ty;      if (i < NumVals[Form] + 1) {        switch (i) {        case 0:          // The first argument is always a pointer. It has a fixed type.          // It is always dereferenced, a nullptr is undefined. -        CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); +        CheckNonNullArgument(*this, APIOrderedArgs[i], ExprRange.getBegin());          // Nothing else to do: we already know all we want about this pointer.          continue;        case 1: @@ -4754,16 +4855,18 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,          if (Form == Init || (Form == Arithmetic && ValType->isIntegerType()))            Ty = ValType;          else if (Form == Copy || Form == Xchg) { -          if (IsPassedByAddress) +          if (IsPassedByAddress) {              // The value pointer is always dereferenced, a nullptr is undefined. -            CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); +            CheckNonNullArgument(*this, APIOrderedArgs[i], +                                 ExprRange.getBegin()); +          }            Ty = ByValType;          } else if (Form == Arithmetic)            Ty = Context.getPointerDiffType();          else { -          Expr *ValArg = TheCall->getArg(i); +          Expr *ValArg = APIOrderedArgs[i];            // The value pointer is always dereferenced, a nullptr is undefined. -          CheckNonNullArgument(*this, ValArg, DRE->getBeginLoc()); +          CheckNonNullArgument(*this, ValArg, ExprRange.getBegin());            LangAS AS = LangAS::Default;            // Keep address space of non-atomic pointer type.            if (const PointerType *PtrTy = @@ -4778,7 +4881,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,          // The third argument to compare_exchange / GNU exchange is the desired          // value, either by-value (for the C11 and *_n variant) or as a pointer.          if (IsPassedByAddress) -          CheckNonNullArgument(*this, TheCall->getArg(i), DRE->getBeginLoc()); +          CheckNonNullArgument(*this, APIOrderedArgs[i], ExprRange.getBegin());          Ty = ByValType;          break;        case 3: @@ -4793,11 +4896,11 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,      InitializedEntity Entity =          InitializedEntity::InitializeParameter(Context, Ty, false); -    ExprResult Arg = TheCall->getArg(i); +    ExprResult Arg = APIOrderedArgs[i];      Arg = PerformCopyInitialization(Entity, SourceLocation(), Arg);      if (Arg.isInvalid())        return true; -    TheCall->setArg(i, Arg.get()); +    APIOrderedArgs[i] = Arg.get();    }    // Permute the arguments into a 'consistent' order. @@ -4806,36 +4909,36 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    switch (Form) {    case Init:      // Note, AtomicExpr::getVal1() has a special case for this atomic. -    SubExprs.push_back(TheCall->getArg(1)); // Val1 +    SubExprs.push_back(APIOrderedArgs[1]); // Val1      break;    case Load: -    SubExprs.push_back(TheCall->getArg(1)); // Order +    SubExprs.push_back(APIOrderedArgs[1]); // Order      break;    case LoadCopy:    case Copy:    case Arithmetic:    case Xchg: -    SubExprs.push_back(TheCall->getArg(2)); // Order -    SubExprs.push_back(TheCall->getArg(1)); // Val1 +    SubExprs.push_back(APIOrderedArgs[2]); // Order +    SubExprs.push_back(APIOrderedArgs[1]); // Val1      break;    case GNUXchg:      // Note, AtomicExpr::getVal2() has a special case for this atomic. -    SubExprs.push_back(TheCall->getArg(3)); // Order -    SubExprs.push_back(TheCall->getArg(1)); // Val1 -    SubExprs.push_back(TheCall->getArg(2)); // Val2 +    SubExprs.push_back(APIOrderedArgs[3]); // Order +    SubExprs.push_back(APIOrderedArgs[1]); // Val1 +    SubExprs.push_back(APIOrderedArgs[2]); // Val2      break;    case C11CmpXchg: -    SubExprs.push_back(TheCall->getArg(3)); // Order -    SubExprs.push_back(TheCall->getArg(1)); // Val1 -    SubExprs.push_back(TheCall->getArg(4)); // OrderFail -    SubExprs.push_back(TheCall->getArg(2)); // Val2 +    SubExprs.push_back(APIOrderedArgs[3]); // Order +    SubExprs.push_back(APIOrderedArgs[1]); // Val1 +    SubExprs.push_back(APIOrderedArgs[4]); // OrderFail +    SubExprs.push_back(APIOrderedArgs[2]); // Val2      break;    case GNUCmpXchg: -    SubExprs.push_back(TheCall->getArg(4)); // Order -    SubExprs.push_back(TheCall->getArg(1)); // Val1 -    SubExprs.push_back(TheCall->getArg(5)); // OrderFail -    SubExprs.push_back(TheCall->getArg(2)); // Val2 -    SubExprs.push_back(TheCall->getArg(3)); // Weak +    SubExprs.push_back(APIOrderedArgs[4]); // Order +    SubExprs.push_back(APIOrderedArgs[1]); // Val1 +    SubExprs.push_back(APIOrderedArgs[5]); // OrderFail +    SubExprs.push_back(APIOrderedArgs[2]); // Val2 +    SubExprs.push_back(APIOrderedArgs[3]); // Weak      break;    } @@ -4849,7 +4952,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,    }    if (auto ScopeModel = AtomicExpr::getScopeModel(Op)) { -    auto *Scope = TheCall->getArg(TheCall->getNumArgs() - 1); +    auto *Scope = Args[Args.size() - 1];      llvm::APSInt Result(32);      if (Scope->isIntegerConstantExpr(Result, Context) &&          !ScopeModel->isValid(Result.getZExtValue())) { @@ -4859,9 +4962,8 @@ ExprResult Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult,      SubExprs.push_back(Scope);    } -  AtomicExpr *AE = -      new (Context) AtomicExpr(TheCall->getCallee()->getBeginLoc(), SubExprs, -                               ResultType, Op, TheCall->getRParenLoc()); +  AtomicExpr *AE = new (Context) +      AtomicExpr(ExprRange.getBegin(), SubExprs, ResultType, Op, RParenLoc);    if ((Op == AtomicExpr::AO__c11_atomic_load ||         Op == AtomicExpr::AO__c11_atomic_store || @@ -5410,7 +5512,7 @@ static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {    if (IsX64 || IsAArch64) {      CallingConv CC = CC_C;      if (const FunctionDecl *FD = S.getCurFunctionDecl()) -      CC = FD->getType()->getAs<FunctionType>()->getCallConv(); +      CC = FD->getType()->castAs<FunctionType>()->getCallConv();      if (IsMSVAStart) {        // Don't allow this in System V ABI functions.        if (CC == CC_X86_64SysV || (!IsWindows && CC != CC_Win64)) @@ -5540,7 +5642,7 @@ bool Sema::SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {                 return false;               if (!Type->isEnumeralType())                 return true; -             const EnumDecl *ED = Type->getAs<EnumType>()->getDecl(); +             const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();               return !(ED &&                        Context.typesAreCompatible(ED->getPromotionType(), Type));             }()) { @@ -5780,7 +5882,7 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {            << SourceRange(TheCall->getArg(0)->getBeginLoc(),                           TheCall->getArg(1)->getEndLoc())); -    numElements = LHSType->getAs<VectorType>()->getNumElements(); +    numElements = LHSType->castAs<VectorType>()->getNumElements();      unsigned numResElements = TheCall->getNumArgs() - 2;      // Check to see if we have a call with 2 vector arguments, the unary shuffle @@ -5788,7 +5890,7 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {      // same number of elts as lhs.      if (TheCall->getNumArgs() == 2) {        if (!RHSType->hasIntegerRepresentation() || -          RHSType->getAs<VectorType>()->getNumElements() != numElements) +          RHSType->castAs<VectorType>()->getNumElements() != numElements)          return ExprError(Diag(TheCall->getBeginLoc(),                                diag::err_vec_builtin_incompatible_vector)                           << TheCall->getDirectCallee() @@ -5801,7 +5903,7 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) {                         << SourceRange(TheCall->getArg(0)->getBeginLoc(),                                        TheCall->getArg(1)->getEndLoc()));      } else if (numElements != numResElements) { -      QualType eltType = LHSType->getAs<VectorType>()->getElementType(); +      QualType eltType = LHSType->castAs<VectorType>()->getElementType();        resType = Context.getVectorType(eltType, numResElements,                                        VectorType::GenericVector);      } @@ -5858,8 +5960,8 @@ ExprResult Sema::SemaConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,                            diag::err_convertvector_non_vector_type));    if (!SrcTy->isDependentType() && !DstTy->isDependentType()) { -    unsigned SrcElts = SrcTy->getAs<VectorType>()->getNumElements(); -    unsigned DstElts = DstTy->getAs<VectorType>()->getNumElements(); +    unsigned SrcElts = SrcTy->castAs<VectorType>()->getNumElements(); +    unsigned DstElts = DstTy->castAs<VectorType>()->getNumElements();      if (SrcElts != DstElts)        return ExprError(Diag(BuiltinLoc,                              diag::err_convertvector_incompatible_vector) @@ -5961,6 +6063,12 @@ bool Sema::SemaBuiltinAssumeAligned(CallExpr *TheCall) {      if (!Result.isPowerOf2())        return Diag(TheCall->getBeginLoc(), diag::err_alignment_not_power_of_two)               << Arg->getSourceRange(); + +    // Alignment calculations can wrap around if it's greater than 2**29. +    unsigned MaximumAlignment = 536870912; +    if (Result > MaximumAlignment) +      Diag(TheCall->getBeginLoc(), diag::warn_assume_aligned_too_great) +          << Arg->getSourceRange() << MaximumAlignment;    }    if (NumArgs > 2) { @@ -6570,7 +6678,8 @@ static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr,                                bool inFunctionCall,                                Sema::VariadicCallType CallType,                                llvm::SmallBitVector &CheckedVarArgs, -                              UncoveredArgHandler &UncoveredArg); +                              UncoveredArgHandler &UncoveredArg, +                              bool IgnoreStringsWithoutSpecifiers);  // Determine if an expression is a string literal or constant string.  // If this function returns false on the arguments to a function expecting a @@ -6583,7 +6692,8 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,                        Sema::VariadicCallType CallType, bool InFunctionCall,                        llvm::SmallBitVector &CheckedVarArgs,                        UncoveredArgHandler &UncoveredArg, -                      llvm::APSInt Offset) { +                      llvm::APSInt Offset, +                      bool IgnoreStringsWithoutSpecifiers = false) {    if (S.isConstantEvaluated())      return SLCT_NotALiteral;   tryAgain: @@ -6634,17 +6744,17 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,        Left = checkFormatStringExpr(S, C->getTrueExpr(), Args,                                     HasVAListArg, format_idx, firstDataArg,                                     Type, CallType, InFunctionCall, -                                   CheckedVarArgs, UncoveredArg, Offset); +                                   CheckedVarArgs, UncoveredArg, Offset, +                                   IgnoreStringsWithoutSpecifiers);        if (Left == SLCT_NotALiteral || !CheckRight) {          return Left;        }      } -    StringLiteralCheckType Right = -        checkFormatStringExpr(S, C->getFalseExpr(), Args, -                              HasVAListArg, format_idx, firstDataArg, -                              Type, CallType, InFunctionCall, CheckedVarArgs, -                              UncoveredArg, Offset); +    StringLiteralCheckType Right = checkFormatStringExpr( +        S, C->getFalseExpr(), Args, HasVAListArg, format_idx, firstDataArg, +        Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset, +        IgnoreStringsWithoutSpecifiers);      return (CheckLeft && Left < Right) ? Left : Right;    } @@ -6748,7 +6858,8 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,          const Expr *Arg = CE->getArg(FA->getFormatIdx().getASTIndex());          StringLiteralCheckType Result = checkFormatStringExpr(              S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, -            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset); +            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset, +            IgnoreStringsWithoutSpecifiers);          if (IsFirst) {            CommonResult = Result;            IsFirst = false; @@ -6766,7 +6877,8 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,                                         HasVAListArg, format_idx,                                         firstDataArg, Type, CallType,                                         InFunctionCall, CheckedVarArgs, -                                       UncoveredArg, Offset); +                                       UncoveredArg, Offset, +                                       IgnoreStringsWithoutSpecifiers);          }        }      } @@ -6775,12 +6887,28 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,    }    case Stmt::ObjCMessageExprClass: {      const auto *ME = cast<ObjCMessageExpr>(E); -    if (const auto *ND = ME->getMethodDecl()) { -      if (const auto *FA = ND->getAttr<FormatArgAttr>()) { +    if (const auto *MD = ME->getMethodDecl()) { +      if (const auto *FA = MD->getAttr<FormatArgAttr>()) { +        // As a special case heuristic, if we're using the method -[NSBundle +        // localizedStringForKey:value:table:], ignore any key strings that lack +        // format specifiers. The idea is that if the key doesn't have any +        // format specifiers then its probably just a key to map to the +        // localized strings. If it does have format specifiers though, then its +        // likely that the text of the key is the format string in the +        // programmer's language, and should be checked. +        const ObjCInterfaceDecl *IFace; +        if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) && +            IFace->getIdentifier()->isStr("NSBundle") && +            MD->getSelector().isKeywordSelector( +                {"localizedStringForKey", "value", "table"})) { +          IgnoreStringsWithoutSpecifiers = true; +        } +          const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());          return checkFormatStringExpr(              S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type, -            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset); +            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset, +            IgnoreStringsWithoutSpecifiers);        }      } @@ -6804,7 +6932,8 @@ checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef<const Expr *> Args,        FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());        CheckFormatString(S, &FStr, E, Args, HasVAListArg, format_idx,                          firstDataArg, Type, InFunctionCall, CallType, -                        CheckedVarArgs, UncoveredArg); +                        CheckedVarArgs, UncoveredArg, +                        IgnoreStringsWithoutSpecifiers);        return SLCT_CheckedLiteral;      } @@ -8072,9 +8201,23 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,      ExprTy = TET->getUnderlyingExpr()->getType();    } -  const analyze_printf::ArgType::MatchKind Match = -      AT.matchesType(S.Context, ExprTy); -  bool Pedantic = Match == analyze_printf::ArgType::NoMatchPedantic; +  // Diagnose attempts to print a boolean value as a character. Unlike other +  // -Wformat diagnostics, this is fine from a type perspective, but it still +  // doesn't make sense. +  if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg && +      E->isKnownToHaveBooleanValue()) { +    const CharSourceRange &CSR = +        getSpecifierRange(StartSpecifier, SpecifierLen); +    SmallString<4> FSString; +    llvm::raw_svector_ostream os(FSString); +    FS.toString(os); +    EmitFormatDiagnostic(S.PDiag(diag::warn_format_bool_as_character) +                             << FSString, +                         E->getExprLoc(), false, CSR); +    return true; +  } + +  analyze_printf::ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);    if (Match == analyze_printf::ArgType::Match)      return true; @@ -8093,9 +8236,14 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,        // function.        if (ICE->getType() == S.Context.IntTy ||            ICE->getType() == S.Context.UnsignedIntTy) { -        // All further checking is done on the subexpression. -        if (AT.matchesType(S.Context, ExprTy)) +        // All further checking is done on the subexpression +        const analyze_printf::ArgType::MatchKind ImplicitMatch = +            AT.matchesType(S.Context, ExprTy); +        if (ImplicitMatch == analyze_printf::ArgType::Match)            return true; +        if (ImplicitMatch == ArgType::NoMatchPedantic || +            ImplicitMatch == ArgType::NoMatchTypeConfusion) +          Match = ImplicitMatch;        }      }    } else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) { @@ -8157,7 +8305,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,        if ((CastTyName == "NSInteger" || CastTyName == "NSUInteger") &&            (AT.isSizeT() || AT.isPtrdiffT()) &&            AT.matchesType(S.Context, CastTy)) -        Pedantic = true; +        Match = ArgType::NoMatchPedantic;        IntendedTy = CastTy;        ShouldNotPrintDirectly = true;      } @@ -8177,10 +8325,20 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,      CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);      if (IntendedTy == ExprTy && !ShouldNotPrintDirectly) { -      unsigned Diag = -          Pedantic -              ? diag::warn_format_conversion_argument_type_mismatch_pedantic -              : diag::warn_format_conversion_argument_type_mismatch; +      unsigned Diag; +      switch (Match) { +      case ArgType::Match: llvm_unreachable("expected non-matching"); +      case ArgType::NoMatchPedantic: +        Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic; +        break; +      case ArgType::NoMatchTypeConfusion: +        Diag = diag::warn_format_conversion_argument_type_mismatch_confusion; +        break; +      case ArgType::NoMatch: +        Diag = diag::warn_format_conversion_argument_type_mismatch; +        break; +      } +        // In this case, the specifier is wrong and should be changed to match        // the argument.        EmitFormatDiagnostic(S.PDiag(Diag) @@ -8236,7 +8394,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,            Name = TypedefTy->getDecl()->getName();          else            Name = CastTyName; -        unsigned Diag = Pedantic +        unsigned Diag = Match == ArgType::NoMatchPedantic                              ? diag::warn_format_argument_needs_cast_pedantic                              : diag::warn_format_argument_needs_cast;          EmitFormatDiagnostic(S.PDiag(Diag) << Name << IntendedTy << IsEnum @@ -8263,10 +8421,19 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,      switch (S.isValidVarArgType(ExprTy)) {      case Sema::VAK_Valid:      case Sema::VAK_ValidInCXX11: { -      unsigned Diag = -          Pedantic -              ? diag::warn_format_conversion_argument_type_mismatch_pedantic -              : diag::warn_format_conversion_argument_type_mismatch; +      unsigned Diag; +      switch (Match) { +      case ArgType::Match: llvm_unreachable("expected non-matching"); +      case ArgType::NoMatchPedantic: +        Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic; +        break; +      case ArgType::NoMatchTypeConfusion: +        Diag = diag::warn_format_conversion_argument_type_mismatch_confusion; +        break; +      case ArgType::NoMatch: +        Diag = diag::warn_format_conversion_argument_type_mismatch; +        break; +      }        EmitFormatDiagnostic(            S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy @@ -8495,7 +8662,8 @@ static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr,                                bool inFunctionCall,                                Sema::VariadicCallType CallType,                                llvm::SmallBitVector &CheckedVarArgs, -                              UncoveredArgHandler &UncoveredArg) { +                              UncoveredArgHandler &UncoveredArg, +                              bool IgnoreStringsWithoutSpecifiers) {    // CHECK: is the format string a wide literal?    if (!FExpr->isAscii() && !FExpr->isUTF8()) {      CheckFormatHandler::EmitFormatDiagnostic( @@ -8516,6 +8684,11 @@ static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr,    size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());    const unsigned numDataArgs = Args.size() - firstDataArg; +  if (IgnoreStringsWithoutSpecifiers && +      !analyze_format_string::parseFormatStringHasFormattingSpecifiers( +          Str, Str + StrLen, S.getLangOpts(), S.Context.getTargetInfo())) +    return; +    // Emit a warning if the string literal is truncated and does not contain an    // embedded null character.    if (TypeSize <= StrRef.size() && @@ -10195,7 +10368,8 @@ static bool IsSameFloatAfterCast(const APValue &value,            IsSameFloatAfterCast(value.getComplexFloatImag(), Src, Tgt));  } -static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC); +static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, +                                       bool IsListInit = false);  static bool IsEnumConstOrFromMacro(Sema &S, Expr *E) {    // Suppress cases where we are comparing against an enum constant. @@ -10627,7 +10801,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,       return false;    if (BitfieldType->isEnumeralType()) { -    EnumDecl *BitfieldEnumDecl = BitfieldType->getAs<EnumType>()->getDecl(); +    EnumDecl *BitfieldEnumDecl = BitfieldType->castAs<EnumType>()->getDecl();      // If the underlying enum type was not explicitly specified as an unsigned      // type and the enum contain only positive values, MSVC++ will cause an      // inconsistency by storing this as a signed type. @@ -10792,6 +10966,26 @@ static void DiagnoseImpCast(Sema &S, Expr *E, QualType T,    DiagnoseImpCast(S, E, E->getType(), T, CContext, diag, pruneControlFlow);  } +static bool isObjCSignedCharBool(Sema &S, QualType Ty) { +  return Ty->isSpecificBuiltinType(BuiltinType::SChar) && +      S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty); +} + +static void adornObjCBoolConversionDiagWithTernaryFixit( +    Sema &S, Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder) { +  Expr *Ignored = SourceExpr->IgnoreImplicit(); +  if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ignored)) +    Ignored = OVE->getSourceExpr(); +  bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) || +                     isa<BinaryOperator>(Ignored) || +                     isa<CXXOperatorCallExpr>(Ignored); +  SourceLocation EndLoc = S.getLocForEndOfToken(SourceExpr->getEndLoc()); +  if (NeedsParens) +    Builder << FixItHint::CreateInsertion(SourceExpr->getBeginLoc(), "(") +            << FixItHint::CreateInsertion(EndLoc, ")"); +  Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO"); +} +  /// Diagnose an implicit cast from a floating point value to an integer value.  static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,                                      SourceLocation CContext) { @@ -10811,6 +11005,13 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,    bool IsConstant =      E->EvaluateAsFloat(Value, S.Context, Expr::SE_AllowSideEffects);    if (!IsConstant) { +    if (isObjCSignedCharBool(S, T)) { +      return adornObjCBoolConversionDiagWithTernaryFixit( +          S, E, +          S.Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool) +              << E->getType()); +    } +      return DiagnoseImpCast(S, E, T, CContext,                             diag::warn_impcast_float_integer, PruneWarnings);    } @@ -10822,6 +11023,23 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,    llvm::APFloat::opStatus Result = Value.convertToInteger(        IntegerValue, llvm::APFloat::rmTowardZero, &isExact); +  // FIXME: Force the precision of the source value down so we don't print +  // digits which are usually useless (we don't really care here if we +  // truncate a digit by accident in edge cases).  Ideally, APFloat::toString +  // would automatically print the shortest representation, but it's a bit +  // tricky to implement. +  SmallString<16> PrettySourceValue; +  unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); +  precision = (precision * 59 + 195) / 196; +  Value.toString(PrettySourceValue, precision); + +  if (isObjCSignedCharBool(S, T) && IntegerValue != 0 && IntegerValue != 1) { +    return adornObjCBoolConversionDiagWithTernaryFixit( +        S, E, +        S.Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool) +            << PrettySourceValue); +  } +    if (Result == llvm::APFloat::opOK && isExact) {      if (IsLiteral) return;      return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer, @@ -10865,16 +11083,6 @@ static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T,      DiagID = diag::warn_impcast_float_to_integer;    } -  // FIXME: Force the precision of the source value down so we don't print -  // digits which are usually useless (we don't really care here if we -  // truncate a digit by accident in edge cases).  Ideally, APFloat::toString -  // would automatically print the shortest representation, but it's a bit -  // tricky to implement. -  SmallString<16> PrettySourceValue; -  unsigned precision = llvm::APFloat::semanticsPrecision(Value.getSemantics()); -  precision = (precision * 59 + 195) / 196; -  Value.toString(PrettySourceValue, precision); -    SmallString<16> PrettyTargetValue;    if (IsBool)      PrettyTargetValue = Value.isZero() ? "false" : "true"; @@ -11151,14 +11359,85 @@ static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T,    return true;  } -static bool isObjCSignedCharBool(Sema &S, QualType Ty) { -  return Ty->isSpecificBuiltinType(BuiltinType::SChar) && -         S.getLangOpts().ObjC && S.NSAPIObj->isObjCBOOLType(Ty); +static const IntegerLiteral *getIntegerLiteral(Expr *E) { +  const auto *IL = dyn_cast<IntegerLiteral>(E); +  if (!IL) { +    if (auto *UO = dyn_cast<UnaryOperator>(E)) { +      if (UO->getOpcode() == UO_Minus) +        return dyn_cast<IntegerLiteral>(UO->getSubExpr()); +    } +  } + +  return IL;  } -static void -CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC, -                        bool *ICContext = nullptr) { +static void CheckConditionalWithEnumTypes(Sema &S, SourceLocation Loc, +                                          Expr *LHS, Expr *RHS) { +  QualType LHSStrippedType = LHS->IgnoreParenImpCasts()->getType(); +  QualType RHSStrippedType = RHS->IgnoreParenImpCasts()->getType(); + +  const auto *LHSEnumType = LHSStrippedType->getAs<EnumType>(); +  if (!LHSEnumType) +    return; +  const auto *RHSEnumType = RHSStrippedType->getAs<EnumType>(); +  if (!RHSEnumType) +    return; + +  // Ignore anonymous enums. +  if (!LHSEnumType->getDecl()->hasNameForLinkage()) +    return; +  if (!RHSEnumType->getDecl()->hasNameForLinkage()) +    return; + +  if (S.Context.hasSameUnqualifiedType(LHSStrippedType, RHSStrippedType)) +    return; + +  S.Diag(Loc, diag::warn_conditional_mixed_enum_types) +      << LHSStrippedType << RHSStrippedType << LHS->getSourceRange() +      << RHS->getSourceRange(); +} + +static void DiagnoseIntInBoolContext(Sema &S, Expr *E) { +  E = E->IgnoreParenImpCasts(); +  SourceLocation ExprLoc = E->getExprLoc(); + +  if (const auto *BO = dyn_cast<BinaryOperator>(E)) { +    BinaryOperator::Opcode Opc = BO->getOpcode(); +    Expr::EvalResult Result; +    // Do not diagnose unsigned shifts. +    if (Opc == BO_Shl) { +      const auto *LHS = getIntegerLiteral(BO->getLHS()); +      const auto *RHS = getIntegerLiteral(BO->getRHS()); +      if (LHS && LHS->getValue() == 0) +        S.Diag(ExprLoc, diag::warn_left_shift_always) << 0; +      else if (!E->isValueDependent() && LHS && RHS && +               RHS->getValue().isNonNegative() && +               E->EvaluateAsInt(Result, S.Context, Expr::SE_AllowSideEffects)) +        S.Diag(ExprLoc, diag::warn_left_shift_always) +            << (Result.Val.getInt() != 0); +      else if (E->getType()->isSignedIntegerType()) +        S.Diag(ExprLoc, diag::warn_left_shift_in_bool_context) << E; +    } +  } + +  if (const auto *CO = dyn_cast<ConditionalOperator>(E)) { +    const auto *LHS = getIntegerLiteral(CO->getTrueExpr()); +    const auto *RHS = getIntegerLiteral(CO->getFalseExpr()); +    if (!LHS || !RHS) +      return; +    if ((LHS->getValue() == 0 || LHS->getValue() == 1) && +        (RHS->getValue() == 0 || RHS->getValue() == 1)) +      // Do not diagnose common idioms. +      return; +    if (LHS->getValue() != 0 && RHS->getValue() != 0) +      S.Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true); +  } +} + +static void CheckImplicitConversion(Sema &S, Expr *E, QualType T, +                                    SourceLocation CC, +                                    bool *ICContext = nullptr, +                                    bool IsListInit = false) {    if (E->isTypeDependent() || E->isValueDependent()) return;    const Type *Source = S.Context.getCanonicalType(E->getType()).getTypePtr(); @@ -11205,19 +11484,13 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,    if (isObjCSignedCharBool(S, T) && Source->isIntegralType(S.Context)) {      Expr::EvalResult Result;      if (E->EvaluateAsInt(Result, S.getASTContext(), -                         Expr::SE_AllowSideEffects) && -        Result.Val.getInt() != 1 && Result.Val.getInt() != 0) { -      auto Builder = S.Diag(CC, diag::warn_impcast_constant_int_to_objc_bool) -                     << Result.Val.getInt().toString(10); -      Expr *Ignored = E->IgnoreImplicit(); -      bool NeedsParens = isa<AbstractConditionalOperator>(Ignored) || -                         isa<BinaryOperator>(Ignored) || -                         isa<CXXOperatorCallExpr>(Ignored); -      SourceLocation EndLoc = S.getLocForEndOfToken(E->getEndLoc()); -      if (NeedsParens) -        Builder << FixItHint::CreateInsertion(E->getBeginLoc(), "(") -                << FixItHint::CreateInsertion(EndLoc, ")"); -      Builder << FixItHint::CreateInsertion(EndLoc, " ? YES : NO"); +                         Expr::SE_AllowSideEffects)) { +      if (Result.Val.getInt() != 1 && Result.Val.getInt() != 0) { +        adornObjCBoolConversionDiagWithTernaryFixit( +            S, E, +            S.Diag(CC, diag::warn_impcast_constant_value_to_objc_bool) +                << Result.Val.getInt().toString(10)); +      }        return;      }    } @@ -11400,10 +11673,61 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,      }    } +  // If we are casting an integer type to a floating point type without +  // initialization-list syntax, we might lose accuracy if the floating +  // point type has a narrower significand than the integer type. +  if (SourceBT && TargetBT && SourceBT->isIntegerType() && +      TargetBT->isFloatingType() && !IsListInit) { +    // Determine the number of precision bits in the source integer type. +    IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated()); +    unsigned int SourcePrecision = SourceRange.Width; + +    // Determine the number of precision bits in the +    // target floating point type. +    unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision( +        S.Context.getFloatTypeSemantics(QualType(TargetBT, 0))); + +    if (SourcePrecision > 0 && TargetPrecision > 0 && +        SourcePrecision > TargetPrecision) { + +      llvm::APSInt SourceInt; +      if (E->isIntegerConstantExpr(SourceInt, S.Context)) { +        // If the source integer is a constant, convert it to the target +        // floating point type. Issue a warning if the value changes +        // during the whole conversion. +        llvm::APFloat TargetFloatValue( +            S.Context.getFloatTypeSemantics(QualType(TargetBT, 0))); +        llvm::APFloat::opStatus ConversionStatus = +            TargetFloatValue.convertFromAPInt( +                SourceInt, SourceBT->isSignedInteger(), +                llvm::APFloat::rmNearestTiesToEven); + +        if (ConversionStatus != llvm::APFloat::opOK) { +          std::string PrettySourceValue = SourceInt.toString(10); +          SmallString<32> PrettyTargetValue; +          TargetFloatValue.toString(PrettyTargetValue, TargetPrecision); + +          S.DiagRuntimeBehavior( +              E->getExprLoc(), E, +              S.PDiag(diag::warn_impcast_integer_float_precision_constant) +                  << PrettySourceValue << PrettyTargetValue << E->getType() << T +                  << E->getSourceRange() << clang::SourceRange(CC)); +        } +      } else { +        // Otherwise, the implicit conversion may lose precision. +        DiagnoseImpCast(S, E, T, CC, +                        diag::warn_impcast_integer_float_precision); +      } +    } +  } +    DiagnoseNullConversion(S, E, T, CC);    S.DiscardMisalignedMemberAddress(Target, E); +  if (Target->isBooleanType()) +    DiagnoseIntInBoolContext(S, E); +    if (!Source->isIntegerType() || !Target->isIntegerType())      return; @@ -11412,6 +11736,14 @@ CheckImplicitConversion(Sema &S, Expr *E, QualType T, SourceLocation CC,    if (Target->isSpecificBuiltinType(BuiltinType::Bool))      return; +  if (isObjCSignedCharBool(S, T) && !Source->isCharType() && +      !E->isKnownToHaveBooleanValue()) { +    return adornObjCBoolConversionDiagWithTernaryFixit( +        S, E, +        S.Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool) +            << E->getType()); +  } +    IntRange SourceRange = GetExprRange(S.Context, E, S.isConstantEvaluated());    IntRange TargetRange = IntRange::forTargetOfCanonicalType(S.Context, Target); @@ -11556,6 +11888,11 @@ static void CheckConditionalOperator(Sema &S, ConditionalOperator *E,    bool Suspicious = false;    CheckConditionalOperand(S, E->getTrueExpr(), T, CC, Suspicious);    CheckConditionalOperand(S, E->getFalseExpr(), T, CC, Suspicious); +  CheckConditionalWithEnumTypes(S, E->getBeginLoc(), E->getTrueExpr(), +                                E->getFalseExpr()); + +  if (T->isBooleanType()) +    DiagnoseIntInBoolContext(S, E);    // If -Wconversion would have warned about either of the candidates    // for a signedness conversion to the context type... @@ -11590,14 +11927,27 @@ static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC) {  /// AnalyzeImplicitConversions - Find and report any interesting  /// implicit conversions in the given expression.  There are a couple  /// of competing diagnostics here, -Wconversion and -Wsign-compare. -static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, -                                       SourceLocation CC) { +static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE, SourceLocation CC, +                                       bool IsListInit/*= false*/) {    QualType T = OrigE->getType();    Expr *E = OrigE->IgnoreParenImpCasts(); +  // Propagate whether we are in a C++ list initialization expression. +  // If so, we do not issue warnings for implicit int-float conversion +  // precision loss, because C++11 narrowing already handles it. +  IsListInit = +      IsListInit || (isa<InitListExpr>(OrigE) && S.getLangOpts().CPlusPlus); +    if (E->isTypeDependent() || E->isValueDependent())      return; +  if (const auto *UO = dyn_cast<UnaryOperator>(E)) +    if (UO->getOpcode() == UO_Not && +        UO->getSubExpr()->isKnownToHaveBooleanValue()) +      S.Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool) +          << OrigE->getSourceRange() << T->isBooleanType() +          << FixItHint::CreateReplacement(UO->getBeginLoc(), "!"); +    // For conditional operators, we analyze the arguments as if they    // were being fed directly into the output.    if (isa<ConditionalOperator>(E)) { @@ -11614,7 +11964,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,    // The non-canonical typecheck is just an optimization;    // CheckImplicitConversion will filter out dead implicit conversions.    if (E->getType() != T) -    CheckImplicitConversion(S, E, T, CC); +    CheckImplicitConversion(S, E, T, CC, nullptr, IsListInit);    // Now continue drilling into this expression. @@ -11624,7 +11974,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,      // FIXME: Use a more uniform representation for this.      for (auto *SE : POE->semantics())        if (auto *OVE = dyn_cast<OpaqueValueExpr>(SE)) -        AnalyzeImplicitConversions(S, OVE->getSourceExpr(), CC); +        AnalyzeImplicitConversions(S, OVE->getSourceExpr(), CC, IsListInit);    }    // Skip past explicit casts. @@ -11632,7 +11982,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,      E = CE->getSubExpr()->IgnoreParenImpCasts();      if (!CE->getType()->isVoidType() && E->getType()->isAtomicType())        S.Diag(E->getBeginLoc(), diag::warn_atomic_implicit_seq_cst); -    return AnalyzeImplicitConversions(S, E, CC); +    return AnalyzeImplicitConversions(S, E, CC, IsListInit);    }    if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { @@ -11671,7 +12021,7 @@ static void AnalyzeImplicitConversions(Sema &S, Expr *OrigE,        // Ignore checking string literals that are in logical and operators.        // This is a common pattern for asserts.        continue; -    AnalyzeImplicitConversions(S, ChildExpr, CC); +    AnalyzeImplicitConversions(S, ChildExpr, CC, IsListInit);    }    if (BO && BO->isLogicalOp()) { @@ -12907,7 +13257,7 @@ void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,    if (ND)      DiagRuntimeBehavior(ND->getBeginLoc(), BaseExpr, -                        PDiag(diag::note_array_index_out_of_bounds) +                        PDiag(diag::note_array_declared_here)                              << ND->getDeclName());  } @@ -14229,7 +14579,7 @@ void Sema::RefersToMemberWithReducedAlignment(      QualType BaseType = ME->getBase()->getType();      if (ME->isArrow())        BaseType = BaseType->getPointeeType(); -    RecordDecl *RD = BaseType->getAs<RecordType>()->getDecl(); +    RecordDecl *RD = BaseType->castAs<RecordType>()->getDecl();      if (RD->isInvalidDecl())        return;  | 
