;
119 unsignedByteNo)
const{
130 unsignedArgCount =
Call->getNumArgs();
131 if(ArgCount >= MinArgCount)
134 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
135<< 0
<< MinArgCount << ArgCount
136<<
0 <<
Call->getSourceRange();
140 unsignedArgCount =
Call->getNumArgs();
141 if(ArgCount <= MaxArgCount)
143 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
144<< 0
<< MaxArgCount << ArgCount
145<<
0 <<
Call->getSourceRange();
149 unsignedMaxArgCount) {
155 unsignedArgCount =
Call->getNumArgs();
156 if(ArgCount == DesiredArgCount)
161assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
165 Call->getArg(ArgCount - 1)->getEndLoc());
168<< 0
<< DesiredArgCount << ArgCount
169<<
0 <<
Call->getArg(1)->getSourceRange();
173 boolHasError =
false;
175 for(
unsignedI = 0; I <
Call->getNumArgs(); ++I) {
182 intDiagMsgKind = -1;
184 if(!ArgString.has_value())
186 else if(ArgString->find(
'$') != std::string::npos)
189 if(DiagMsgKind >= 0) {
200 if(
Value->isTypeDependent())
223S.
Diag(ValArg->
getBeginLoc(), diag::err_builtin_annotation_first_arg)
231 if(!Literal || !Literal->isOrdinary()) {
232S.
Diag(StrArg->
getBeginLoc(), diag::err_builtin_annotation_second_arg)
244S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
252 auto*Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
253 if(!Literal || !Literal->isWide()) {
254S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
255<< Arg->getSourceRange();
271 if(ResultType.
isNull())
275TheCall->
setType(ResultType);
289 const FunctionDecl*FD = dyn_cast_or_null<FunctionDecl>(
293S.
Diag(TheCall->
getBeginLoc(), diag::err_function_start_invalid_type)
320 boolIsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
322 autoIsValidIntegerType = [](
QualTypeTy) {
323 returnTy->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
330 if((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
334S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
340 if(!IsValidIntegerType(AlignOp->
getType())) {
351llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
352llvm::APSInt MaxValue(
353llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
354 if(AlignValue < 1) {
355S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
358 if(llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
363 if(!AlignValue.isPowerOf2()) {
364S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
367 if(AlignValue == 1) {
368S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
369<< IsBooleanAlignBuiltin;
397std::pair<unsigned, const char *> Builtins[] = {
398{ Builtin::BI__builtin_add_overflow,
"ckd_add"},
399{ Builtin::BI__builtin_sub_overflow,
"ckd_sub"},
400{ Builtin::BI__builtin_mul_overflow,
"ckd_mul"},
403 boolCkdOperation = llvm::any_of(Builtins, [&](
conststd::pair<
unsigned,
404 const char*> &
P) {
405 returnBuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
410 autoValidCkdIntType = [](
QualTypeQT) {
413 if(
const auto*BT = QT.getCanonicalType()->getAs<
BuiltinType>())
414 return(BT->getKind() >= BuiltinType::Short &&
415BT->getKind() <= BuiltinType::Int128) || (
416BT->getKind() >= BuiltinType::UShort &&
417BT->getKind() <= BuiltinType::UInt128) ||
418BT->getKind() == BuiltinType::UChar ||
419BT->getKind() == BuiltinType::SChar;
424 for(
unsignedI = 0; I < 2; ++I) {
430 boolIsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
449!PtrTy->getPointeeType()->isIntegerType() ||
450(!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
451PtrTy->getPointeeType().isConstQualified()) {
453diag::err_overflow_builtin_must_be_ptr_int)
461 if(BuiltinID == Builtin::BI__builtin_mul_overflow) {
462 for(
unsignedI = 0; I < 3; ++I) {
463 const autoArg = TheCall->
getArg(I);
466 if(Ty->isBitIntType() && Ty->isSignedIntegerType() &&
468 returnS.
Diag(Arg->getBeginLoc(),
469diag::err_overflow_builtin_bit_int_max_size)
478structBuiltinDumpStructGenerator {
487: S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
488Policy(S.Context.getPrintingPolicy()) {
492 Expr*makeOpaqueValueExpr(
Expr*Inner) {
495Inner->getObjectKind(), Inner);
496Actions.push_back(OVE);
500 Expr*getStringLiteral(llvm::StringRef Str) {
506 boolcallPrintFunction(llvm::StringRef Format,
510Args.reserve((TheCall->
getNumArgs() - 2) +
1 + Exprs.size());
512Args.push_back(getStringLiteral(Format));
513Args.insert(Args.end(), Exprs.begin(), Exprs.end());
518Ctx.PointOfInstantiation =
Loc;
519Ctx.CallArgs = Args.data();
520Ctx.NumCallArgs = Args.size();
529Actions.push_back(RealCall.
get());
535 Expr*getIndentString(
unsignedDepth) {
541 returngetStringLiteral(Indent);
545 returngetStringLiteral(
T.getAsString(Policy));
549llvm::raw_svector_ostream OS(Str);
554 switch(BT->getKind()) {
555 caseBuiltinType::Bool:
558 caseBuiltinType::Char_U:
559 caseBuiltinType::UChar:
562 caseBuiltinType::Char_S:
563 caseBuiltinType::SChar:
575analyze_printf::PrintfConversionSpecifier::sArg) {
601 booldumpUnnamedRecord(
const RecordDecl*RD,
Expr*
E,
unsignedDepth) {
602 Expr*IndentLit = getIndentString(Depth);
604 if(IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
605: callPrintFunction(
"%s", {TypeLit}))
608 returndumpRecordValue(RD,
E, IndentLit, Depth);
621 Expr*RecordArg = makeOpaqueValueExpr(
E);
624 if(callPrintFunction(
" {\n"))
628 if(
const auto*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
629 for(
const auto&
Base: CXXRD->bases()) {
637dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
643 Expr*FieldIndentArg = getIndentString(Depth + 1);
646 for(
auto*
D: RD->
decls()) {
647 auto*IFD = dyn_cast<IndirectFieldDecl>(
D);
648 auto*FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
649 if(!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
655getStringLiteral(FD->getName())};
657 if(FD->isBitField()) {
661FD->getBitWidthValue());
675 if(
Field.isInvalid())
678 auto*InnerRD = FD->getType()->getAsRecordDecl();
679 auto*InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
680 if(InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
682 if(callPrintFunction(Format, Args) ||
683dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
687 if(appendFormatSpecifier(FD->getType(), Format)) {
689Args.push_back(
Field.get());
699Args.push_back(FieldAddr.
get());
702 if(callPrintFunction(Format, Args))
707 returnRecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
708: callPrintFunction(
"}\n");
711 Expr*buildWrapper() {
714TheCall->
setType(Wrapper->getType());
728TheCall->
setArg(0, PtrArgResult.
get());
735diag::err_expected_struct_pointer_argument)
744diag::err_incomplete_type))
753 switch(BT ? BT->getKind() : BuiltinType::Void) {
754 caseBuiltinType::Dependent:
755 caseBuiltinType::Overload:
756 caseBuiltinType::BoundMember:
757 caseBuiltinType::PseudoObject:
758 caseBuiltinType::UnknownAny:
759 caseBuiltinType::BuiltinFn:
765diag::err_expected_callable_argument)
771BuiltinDumpStructGenerator Generator(S, TheCall);
777 Expr*PtrArg = PtrArgResult.
get();
781 if(Generator.dumpUnnamedRecord(RD, PtrArg, 0))
784 returnGenerator.buildWrapper();
796 if(
Call->getStmtClass() != Stmt::CallExprClass) {
797S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
798<<
Call->getSourceRange();
802 autoCE = cast<CallExpr>(
Call);
803 if(CE->getCallee()->getType()->isBlockPointerType()) {
804S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
805<<
Call->getSourceRange();
809 const Decl*TargetDecl = CE->getCalleeDecl();
810 if(
const FunctionDecl*FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
811 if(FD->getBuiltinID()) {
812S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
813<<
Call->getSourceRange();
817 if(isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
818S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
819<<
Call->getSourceRange();
827S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
841BuiltinCall->
setType(CE->getType());
845BuiltinCall->
setArg(1, ChainResult.
get());
852classScanfDiagnosticFormatHandler
856 usingComputeSizeFunction =
857llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
861 usingDiagnoseFunction =
862llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
864ComputeSizeFunction ComputeSizeArgument;
865DiagnoseFunction Diagnose;
868ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
869DiagnoseFunction Diagnose)
870: ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
873 const char*StartSpecifier,
874 unsignedspecifierLen)
override{
875 if(!FS.consumesDataArgument())
878 unsignedNulByte = 0;
879 switch((FS.getConversionSpecifier().getKind())) {
892analyze_format_string::OptionalAmount::HowSpecified::Constant)
897std::optional<llvm::APSInt> DestSizeAPS =
898ComputeSizeArgument(FS.getArgIndex());
902 unsignedDestSize = DestSizeAPS->getZExtValue();
904 if(DestSize < SourceSize)
905Diagnose(FS.getArgIndex(), DestSize, SourceSize);
911classEstimateSizeFormatHandler
916 boolIsKernelCompatible =
true;
919EstimateSizeFormatHandler(StringRef Format)
920:
Size(
std::
min(Format.find(0), Format.size()) +
924 const char*,
unsignedSpecifierLen,
927 const size_tFieldWidth = computeFieldWidth(FS);
928 const size_tPrecision = computePrecision(FS);
931 switch(FS.getConversionSpecifier().getKind()) {
935 Size+= std::max(FieldWidth, (
size_t)1);
947 Size+= std::max(FieldWidth, Precision);
963 Size+= std::max(FieldWidth, 1
+
964(Precision ? 1 + Precision
974(Precision ? 1 + Precision : 0)
+
984(Precision ? 1 + Precision : 0)
+
999IsKernelCompatible =
false;
1000 Size+= std::max(FieldWidth, 2
+ Precision);
1012 Size+= FS.hasPlusPrefix() || FS.hasSpacePrefix();
1014 if(FS.hasAlternativeForm()) {
1015 switch(FS.getConversionSpecifier().getKind()) {
1044 Size+= (Precision ? 0 : 1);
1051assert(SpecifierLen <= Size &&
"no underflow");
1052 Size-= SpecifierLen;
1056 size_tgetSizeLowerBound()
const{
return Size; }
1057 boolisKernelCompatible()
const{
returnIsKernelCompatible; }
1062 size_tFieldWidth = 0;
1070 size_tPrecision = 0;
1075 switch(FS.getConversionSpecifier().getKind()) {
1117StringRef &FormatStrRef,
size_t&StrLen,
1119 if(
const auto*Format = dyn_cast<StringLiteral>(FormatExpr);
1120Format && (Format->isOrdinary() || Format->isUTF8())) {
1121FormatStrRef = Format->getString();
1124assert(
T&&
"String literal not of constant array type!");
1125 size_tTypeSize =
T->getZExtSize();
1127StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1133voidSema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl*FD,
1139 boolUseDABAttr =
false;
1142 const auto*DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1144UseDecl = DABAttr->getFunction();
1145assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1157 autoTranslateIndex = [&](
unsignedIndex) -> std::optional<unsigned> {
1164 unsignedDABIndices = DABAttr->argIndices_size();
1165 unsignedNewIndex = Index < DABIndices
1166? DABAttr->argIndices_begin()[Index]
1169 returnstd::nullopt;
1173 autoComputeExplicitObjectSizeArgument =
1174[&](
unsignedIndex) -> std::optional<llvm::APSInt> {
1175std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1177 returnstd::nullopt;
1178 unsignedNewIndex = *IndexOptional;
1182 returnstd::nullopt;
1184 Integer.setIsUnsigned(
true);
1188 autoComputeSizeArgument =
1189[&](
unsignedIndex) -> std::optional<llvm::APSInt> {
1195 if(Index < FD->getNumParams()) {
1196 if(
const auto*POS =
1198BOSType = POS->getType();
1201std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1203 returnstd::nullopt;
1204 unsignedNewIndex = *IndexOptional;
1207 returnstd::nullopt;
1209 const Expr*ObjArg = TheCall->
getArg(NewIndex);
1212 returnstd::nullopt;
1215 returnllvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1218 autoComputeStrLenArgument =
1219[&](
unsignedIndex) -> std::optional<llvm::APSInt> {
1220std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1222 returnstd::nullopt;
1223 unsignedNewIndex = *IndexOptional;
1225 const Expr*ObjArg = TheCall->
getArg(NewIndex);
1228 returnstd::nullopt;
1230 returnllvm::APSInt::getUnsigned(
Result+ 1).extOrTrunc(SizeTypeWidth);
1233std::optional<llvm::APSInt> SourceSize;
1234std::optional<llvm::APSInt> DestinationSize;
1235 unsignedDiagID = 0;
1236 boolIsChkVariant =
false;
1238 autoGetFunctionName = [&]() {
1244FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1245FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1247FunctionName.consume_front(
"__builtin_");
1249 returnFunctionName;
1252 switch(BuiltinID) {
1255 caseBuiltin::BI__builtin_strcpy:
1256 caseBuiltin::BIstrcpy: {
1257DiagID = diag::warn_fortify_strlen_overflow;
1258SourceSize = ComputeStrLenArgument(1);
1259DestinationSize = ComputeSizeArgument(0);
1263 caseBuiltin::BI__builtin___strcpy_chk: {
1264DiagID = diag::warn_fortify_strlen_overflow;
1265SourceSize = ComputeStrLenArgument(1);
1266DestinationSize = ComputeExplicitObjectSizeArgument(2);
1267IsChkVariant =
true;
1271 caseBuiltin::BIscanf:
1272 caseBuiltin::BIfscanf:
1273 caseBuiltin::BIsscanf: {
1274 unsignedFormatIndex = 1;
1275 unsignedDataIndex = 2;
1276 if(BuiltinID == Builtin::BIscanf) {
1281 const auto*FormatExpr =
1284StringRef FormatStrRef;
1289 auto Diagnose= [&](
unsignedArgIndex,
unsignedDestSize,
1290 unsignedSourceSize) {
1291DiagID = diag::warn_fortify_scanf_overflow;
1292 unsignedIndex = ArgIndex + DataIndex;
1293StringRef FunctionName = GetFunctionName();
1295 PDiag(DiagID) << FunctionName << (Index + 1)
1296<< DestSize << SourceSize);
1299 autoShiftedComputeSizeArgument = [&](
unsignedIndex) {
1300 returnComputeSizeArgument(Index + DataIndex);
1302ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1303 const char*FormatBytes = FormatStrRef.data();
1314 caseBuiltin::BIsprintf:
1315 caseBuiltin::BI__builtin___sprintf_chk: {
1316 size_tFormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1319StringRef FormatStrRef;
1322EstimateSizeFormatHandler H(FormatStrRef);
1323 const char*FormatBytes = FormatStrRef.data();
1325H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1327DiagID = H.isKernelCompatible()
1328? diag::warn_format_overflow
1329: diag::warn_format_overflow_non_kprintf;
1330SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1331.extOrTrunc(SizeTypeWidth);
1332 if(BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1333DestinationSize = ComputeExplicitObjectSizeArgument(2);
1334IsChkVariant =
true;
1336DestinationSize = ComputeSizeArgument(0);
1343 caseBuiltin::BI__builtin___memcpy_chk:
1344 caseBuiltin::BI__builtin___memmove_chk:
1345 caseBuiltin::BI__builtin___memset_chk:
1346 caseBuiltin::BI__builtin___strlcat_chk:
1347 caseBuiltin::BI__builtin___strlcpy_chk:
1348 caseBuiltin::BI__builtin___strncat_chk:
1349 caseBuiltin::BI__builtin___strncpy_chk:
1350 caseBuiltin::BI__builtin___stpncpy_chk:
1351 caseBuiltin::BI__builtin___memccpy_chk:
1352 caseBuiltin::BI__builtin___mempcpy_chk: {
1353DiagID = diag::warn_builtin_chk_overflow;
1354SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1356ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1357IsChkVariant =
true;
1361 caseBuiltin::BI__builtin___snprintf_chk:
1362 caseBuiltin::BI__builtin___vsnprintf_chk: {
1363DiagID = diag::warn_builtin_chk_overflow;
1364SourceSize = ComputeExplicitObjectSizeArgument(1);
1365DestinationSize = ComputeExplicitObjectSizeArgument(3);
1366IsChkVariant =
true;
1370 caseBuiltin::BIstrncat:
1371 caseBuiltin::BI__builtin_strncat:
1372 caseBuiltin::BIstrncpy:
1373 caseBuiltin::BI__builtin_strncpy:
1374 caseBuiltin::BIstpncpy:
1375 caseBuiltin::BI__builtin_stpncpy: {
1381DiagID = diag::warn_fortify_source_size_mismatch;
1382SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1383DestinationSize = ComputeSizeArgument(0);
1387 caseBuiltin::BImemcpy:
1388 caseBuiltin::BI__builtin_memcpy:
1389 caseBuiltin::BImemmove:
1390 caseBuiltin::BI__builtin_memmove:
1391 caseBuiltin::BImemset:
1392 caseBuiltin::BI__builtin_memset:
1393 caseBuiltin::BImempcpy:
1394 caseBuiltin::BI__builtin_mempcpy: {
1395DiagID = diag::warn_fortify_source_overflow;
1396SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397DestinationSize = ComputeSizeArgument(0);
1400 caseBuiltin::BIsnprintf:
1401 caseBuiltin::BI__builtin_snprintf:
1402 caseBuiltin::BIvsnprintf:
1403 caseBuiltin::BI__builtin_vsnprintf: {
1404DiagID = diag::warn_fortify_source_size_mismatch;
1405SourceSize = ComputeExplicitObjectSizeArgument(1);
1407StringRef FormatStrRef;
1411EstimateSizeFormatHandler H(FormatStrRef);
1412 const char*FormatBytes = FormatStrRef.data();
1414H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1416llvm::APSInt FormatSize =
1417llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1418.extOrTrunc(SizeTypeWidth);
1419 if(FormatSize > *SourceSize && *SourceSize != 0) {
1420 unsignedTruncationDiagID =
1421H.isKernelCompatible() ? diag::warn_format_truncation
1422: diag::warn_format_truncation_non_kprintf;
1425SourceSize->toString(SpecifiedSizeStr,
10);
1426FormatSize.toString(FormatSizeStr,
10);
1428 PDiag(TruncationDiagID)
1429<< GetFunctionName() << SpecifiedSizeStr
1434DestinationSize = ComputeSizeArgument(0);
1438 if(!SourceSize || !DestinationSize ||
1439llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1442StringRef FunctionName = GetFunctionName();
1446DestinationSize->toString(DestinationStr,
10);
1447SourceSize->toString(SourceStr,
10);
1450<< FunctionName << DestinationStr << SourceStr);
1463 while(S && !S->isSEHExceptScope())
1465 if(!S || !(S->getFlags() & NeededScopeFlags)) {
1468<< DRE->getDecl()->getIdentifier();
1480 "__builtin_alloca has invalid address space");
1488enumPointerAuthOpKind {
1537llvm::raw_svector_ostream Str(
Value);
1546 Result= KeyValue->getZExtValue();
1550staticstd::pair<const ValueDecl *, CharUnits>
1557 const auto*BaseDecl =
1562 return{BaseDecl,
Result.Val.getLValueOffset()};
1566 boolRequireConstant =
false) {
1574 autoAllowsPointer = [](PointerAuthOpKind OpKind) {
1575 returnOpKind != PAO_BlendInteger;
1577 autoAllowsInteger = [](PointerAuthOpKind OpKind) {
1578 returnOpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1579OpKind == PAO_SignGeneric;
1588}
else if(AllowsInteger(OpKind) &&
1595<<
unsigned(OpKind == PAO_Discriminator ? 1
1596: OpKind == PAO_BlendPointer ? 2
1597: OpKind == PAO_BlendInteger ? 3
1599<<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1609 if(!RequireConstant) {
1611 if((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1614? diag::warn_ptrauth_sign_null_pointer
1615: diag::warn_ptrauth_auth_null_pointer)
1625 if(OpKind == PAO_Sign) {
1635 else if(isa<FunctionDecl>(BaseDecl))
1643S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1648assert(OpKind == PAO_Discriminator);
1654 if(
Call->getBuiltinCallee() ==
1655Builtin::BI__builtin_ptrauth_blend_discriminator) {
1670assert(
Pointer->getType()->isPointerType());
1676 if(!BaseDecl || !isa<VarDecl>(BaseDecl))
1682assert(
Integer->getType()->isIntegerType());
1688S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1701 Call->setType(
Call->getArgs()[0]->getType());
1732PointerAuthOpKind OpKind,
1733 boolRequireConstant) {
1744 Call->setType(
Call->getArgs()[0]->getType());
1760 Call->setType(
Call->getArgs()[0]->getType());
1769 const Expr*Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1772 const auto*Literal = dyn_cast<StringLiteral>(Arg);
1773 if(!Literal || Literal->getCharByteWidth() != 1) {
1774S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_string_not_literal)
1803 autoDiagSelect = [&]() -> std::optional<unsigned> {
1810 returnstd::optional<unsigned>{};
1813S.
Diag(TheCall->
getBeginLoc(), diag::err_builtin_launder_invalid_arg)
1825diag::err_incomplete_type))
1829 "Unhandled non-object pointer case");
1857 if(PT->getPointeeType()->isFunctionType()) {
1859diag::err_builtin_is_within_lifetime_invalid_arg)
1865 if(PT->getPointeeType()->isVariableArrayType()) {
1867<< 1 <<
"__builtin_is_within_lifetime";
1872diag::err_builtin_is_within_lifetime_invalid_arg)
1885llvm::Triple::ObjectFormatType CurObjFormat =
1887 if(llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1888S.
Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
1900llvm::Triple::ArchType CurArch =
1902 if(llvm::is_contained(SupportedArchs, CurArch))
1904S.
Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
1912boolSema::CheckTSBuiltinFunctionCall(
const TargetInfo&TI,
unsignedBuiltinID,
1919 casellvm::Triple::arm:
1920 casellvm::Triple::armeb:
1921 casellvm::Triple::thumb:
1922 casellvm::Triple::thumbeb:
1924 casellvm::Triple::aarch64:
1925 casellvm::Triple::aarch64_32:
1926 casellvm::Triple::aarch64_be:
1928 casellvm::Triple::bpfeb:
1929 casellvm::Triple::bpfel:
1931 casellvm::Triple::hexagon:
1933 casellvm::Triple::mips:
1934 casellvm::Triple::mipsel:
1935 casellvm::Triple::mips64:
1936 casellvm::Triple::mips64el:
1938 casellvm::Triple::spirv:
1940 casellvm::Triple::systemz:
1942 casellvm::Triple::x86:
1943 casellvm::Triple::x86_64:
1945 casellvm::Triple::ppc:
1946 casellvm::Triple::ppcle:
1947 casellvm::Triple::ppc64:
1948 casellvm::Triple::ppc64le:
1950 casellvm::Triple::amdgcn:
1952 casellvm::Triple::riscv32:
1953 casellvm::Triple::riscv64:
1955 casellvm::Triple::loongarch32:
1956 casellvm::Triple::loongarch64:
1959 casellvm::Triple::wasm32:
1960 casellvm::Triple::wasm64:
1962 casellvm::Triple::nvptx:
1963 casellvm::Triple::nvptx64:
1975 returnS.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1976<< ArgIndex <<
0 << ArgTy;
1986EltTy = VecTy->getElementType();
1989 returnS.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1990<< ArgIndex <<
5 << ArgTy;
2000 const TargetInfo*AuxTI,
unsignedBuiltinID) {
2001assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2002BuiltinID == Builtin::BI__builtin_cpu_is) &&
2003 "Expecting __builtin_cpu_...");
2005 boolIsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2007 autoSupportsBI = [=](
const TargetInfo*TInfo) {
2008 returnTInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2009(!IsCPUSupports && TInfo->supportsCpuIs()));
2011 if(!SupportsBI(&TI) && SupportsBI(AuxTI))
2018? diag::err_builtin_aix_os_unsupported
2019: diag::err_builtin_target_unsupported)
2024 if(!isa<StringLiteral>(Arg))
2025 returnS.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2029StringRef Feature = cast<StringLiteral>(Arg)->getString();
2052TheCall->
setArg(0, Arg);
2076TheCall->
setArg(0, Arg0);
2082<< 1 <<
7 << Arg0Ty;
2092TheCall->
setArg(1, Arg1);
2098<< 2 <<
8 << Arg1Ty;
2107Sema::CheckBuiltinFunctionCall(
FunctionDecl*FDecl,
unsignedBuiltinID,
2112 unsignedICEArguments = 0;
2119 for(
unsignedArgNo = 0; ICEArguments != 0; ++ArgNo) {
2121 if((ICEArguments & (1 << ArgNo)) == 0)
continue;
2126 if(ArgNo < TheCall->getNumArgs() &&
2129ICEArguments &= ~(1 << ArgNo);
2133 switch(BuiltinID) {
2134 caseBuiltin::BI__builtin_cpu_supports:
2135 caseBuiltin::BI__builtin_cpu_is:
2140 caseBuiltin::BI__builtin_cpu_init:
2147 caseBuiltin::BI__builtin___CFStringMakeConstantString:
2151*
this, BuiltinID, TheCall,
2152{llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2155 "Wrong # arguments to builtin CFStringMakeConstantString");
2156 if(
ObjC().CheckObjCString(TheCall->
getArg(0)))
2159 caseBuiltin::BI__builtin_ms_va_start:
2160 caseBuiltin::BI__builtin_stdarg_start:
2161 caseBuiltin::BI__builtin_va_start:
2162 if(BuiltinVAStart(BuiltinID, TheCall))
2165 caseBuiltin::BI__va_start: {
2167 casellvm::Triple::aarch64:
2168 casellvm::Triple::arm:
2169 casellvm::Triple::thumb:
2170 if(BuiltinVAStartARMMicrosoft(TheCall))
2174 if(BuiltinVAStart(BuiltinID, TheCall))
2182 caseBuiltin::BI_interlockedbittestandset_acq:
2183 caseBuiltin::BI_interlockedbittestandset_rel:
2184 caseBuiltin::BI_interlockedbittestandset_nf:
2185 caseBuiltin::BI_interlockedbittestandreset_acq:
2186 caseBuiltin::BI_interlockedbittestandreset_rel:
2187 caseBuiltin::BI_interlockedbittestandreset_nf:
2190{llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2195 caseBuiltin::BI_bittest64:
2196 caseBuiltin::BI_bittestandcomplement64:
2197 caseBuiltin::BI_bittestandreset64:
2198 caseBuiltin::BI_bittestandset64:
2199 caseBuiltin::BI_interlockedbittestandreset64:
2200 caseBuiltin::BI_interlockedbittestandset64:
2203{llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2204llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2208 caseBuiltin::BI__builtin_set_flt_rounds:
2211{llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2212llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2213llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2214llvm::Triple::ppc64le}))
2218 caseBuiltin::BI__builtin_isgreater:
2219 caseBuiltin::BI__builtin_isgreaterequal:
2220 caseBuiltin::BI__builtin_isless:
2221 caseBuiltin::BI__builtin_islessequal:
2222 caseBuiltin::BI__builtin_islessgreater:
2223 caseBuiltin::BI__builtin_isunordered:
2224 if(BuiltinUnorderedCompare(TheCall, BuiltinID))
2227 caseBuiltin::BI__builtin_fpclassify:
2228 if(BuiltinFPClassification(TheCall, 6, BuiltinID))
2231 caseBuiltin::BI__builtin_isfpclass:
2232 if(BuiltinFPClassification(TheCall, 2, BuiltinID))
2235 caseBuiltin::BI__builtin_isfinite:
2236 caseBuiltin::BI__builtin_isinf:
2237 caseBuiltin::BI__builtin_isinf_sign:
2238 caseBuiltin::BI__builtin_isnan:
2239 caseBuiltin::BI__builtin_issignaling:
2240 caseBuiltin::BI__builtin_isnormal:
2241 caseBuiltin::BI__builtin_issubnormal:
2242 caseBuiltin::BI__builtin_iszero:
2243 caseBuiltin::BI__builtin_signbit:
2244 caseBuiltin::BI__builtin_signbitf:
2245 caseBuiltin::BI__builtin_signbitl:
2246 if(BuiltinFPClassification(TheCall, 1, BuiltinID))
2249 caseBuiltin::BI__builtin_shufflevector:
2253 caseBuiltin::BI__builtin_prefetch:
2254 if(BuiltinPrefetch(TheCall))
2257 caseBuiltin::BI__builtin_alloca_with_align:
2258 caseBuiltin::BI__builtin_alloca_with_align_uninitialized:
2259 if(BuiltinAllocaWithAlign(TheCall))
2262 caseBuiltin::BI__builtin_alloca:
2263 caseBuiltin::BI__builtin_alloca_uninitialized:
2270 caseBuiltin::BI__arithmetic_fence:
2271 if(BuiltinArithmeticFence(TheCall))
2274 caseBuiltin::BI__assume:
2275 caseBuiltin::BI__builtin_assume:
2276 if(BuiltinAssume(TheCall))
2279 caseBuiltin::BI__builtin_assume_aligned:
2280 if(BuiltinAssumeAligned(TheCall))
2283 caseBuiltin::BI__builtin_dynamic_object_size:
2284 caseBuiltin::BI__builtin_object_size:
2288 caseBuiltin::BI__builtin_longjmp:
2289 if(BuiltinLongjmp(TheCall))
2292 caseBuiltin::BI__builtin_setjmp:
2293 if(BuiltinSetjmp(TheCall))
2296 caseBuiltin::BI__builtin_classify_type:
2301 caseBuiltin::BI__builtin_complex:
2302 if(BuiltinComplex(TheCall))
2305 caseBuiltin::BI__builtin_constant_p: {
2314 caseBuiltin::BI__builtin_launder:
2316 caseBuiltin::BI__builtin_is_within_lifetime:
2318 caseBuiltin::BI__sync_fetch_and_add:
2319 caseBuiltin::BI__sync_fetch_and_add_1:
2320 caseBuiltin::BI__sync_fetch_and_add_2:
2321 caseBuiltin::BI__sync_fetch_and_add_4:
2322 caseBuiltin::BI__sync_fetch_and_add_8:
2323 caseBuiltin::BI__sync_fetch_and_add_16:
2324 caseBuiltin::BI__sync_fetch_and_sub:
2325 caseBuiltin::BI__sync_fetch_and_sub_1:
2326 caseBuiltin::BI__sync_fetch_and_sub_2:
2327 caseBuiltin::BI__sync_fetch_and_sub_4:
2328 caseBuiltin::BI__sync_fetch_and_sub_8:
2329 caseBuiltin::BI__sync_fetch_and_sub_16:
2330 caseBuiltin::BI__sync_fetch_and_or:
2331 caseBuiltin::BI__sync_fetch_and_or_1:
2332 caseBuiltin::BI__sync_fetch_and_or_2:
2333 caseBuiltin::BI__sync_fetch_and_or_4:
2334 caseBuiltin::BI__sync_fetch_and_or_8:
2335 caseBuiltin::BI__sync_fetch_and_or_16:
2336 caseBuiltin::BI__sync_fetch_and_and:
2337 caseBuiltin::BI__sync_fetch_and_and_1:
2338 caseBuiltin::BI__sync_fetch_and_and_2:
2339 caseBuiltin::BI__sync_fetch_and_and_4:
2340 caseBuiltin::BI__sync_fetch_and_and_8:
2341 caseBuiltin::BI__sync_fetch_and_and_16:
2342 caseBuiltin::BI__sync_fetch_and_xor:
2343 caseBuiltin::BI__sync_fetch_and_xor_1:
2344 caseBuiltin::BI__sync_fetch_and_xor_2:
2345 caseBuiltin::BI__sync_fetch_and_xor_4:
2346 caseBuiltin::BI__sync_fetch_and_xor_8:
2347 caseBuiltin::BI__sync_fetch_and_xor_16:
2348 caseBuiltin::BI__sync_fetch_and_nand:
2349 caseBuiltin::BI__sync_fetch_and_nand_1:
2350 caseBuiltin::BI__sync_fetch_and_nand_2:
2351 caseBuiltin::BI__sync_fetch_and_nand_4:
2352 caseBuiltin::BI__sync_fetch_and_nand_8:
2353 caseBuiltin::BI__sync_fetch_and_nand_16:
2354 caseBuiltin::BI__sync_add_and_fetch:
2355 caseBuiltin::BI__sync_add_and_fetch_1:
2356 caseBuiltin::BI__sync_add_and_fetch_2:
2357 caseBuiltin::BI__sync_add_and_fetch_4:
2358 caseBuiltin::BI__sync_add_and_fetch_8:
2359 caseBuiltin::BI__sync_add_and_fetch_16:
2360 caseBuiltin::BI__sync_sub_and_fetch:
2361 caseBuiltin::BI__sync_sub_and_fetch_1:
2362 caseBuiltin::BI__sync_sub_and_fetch_2:
2363 caseBuiltin::BI__sync_sub_and_fetch_4:
2364 caseBuiltin::BI__sync_sub_and_fetch_8:
2365 caseBuiltin::BI__sync_sub_and_fetch_16:
2366 caseBuiltin::BI__sync_and_and_fetch:
2367 caseBuiltin::BI__sync_and_and_fetch_1:
2368 caseBuiltin::BI__sync_and_and_fetch_2:
2369 caseBuiltin::BI__sync_and_and_fetch_4:
2370 caseBuiltin::BI__sync_and_and_fetch_8:
2371 caseBuiltin::BI__sync_and_and_fetch_16:
2372 caseBuiltin::BI__sync_or_and_fetch:
2373 caseBuiltin::BI__sync_or_and_fetch_1:
2374 caseBuiltin::BI__sync_or_and_fetch_2:
2375 caseBuiltin::BI__sync_or_and_fetch_4:
2376 caseBuiltin::BI__sync_or_and_fetch_8:
2377 caseBuiltin::BI__sync_or_and_fetch_16:
2378 caseBuiltin::BI__sync_xor_and_fetch:
2379 caseBuiltin::BI__sync_xor_and_fetch_1:
2380 caseBuiltin::BI__sync_xor_and_fetch_2:
2381 caseBuiltin::BI__sync_xor_and_fetch_4:
2382 caseBuiltin::BI__sync_xor_and_fetch_8:
2383 caseBuiltin::BI__sync_xor_and_fetch_16:
2384 caseBuiltin::BI__sync_nand_and_fetch:
2385 caseBuiltin::BI__sync_nand_and_fetch_1:
2386 caseBuiltin::BI__sync_nand_and_fetch_2:
2387 caseBuiltin::BI__sync_nand_and_fetch_4:
2388 caseBuiltin::BI__sync_nand_and_fetch_8:
2389 caseBuiltin::BI__sync_nand_and_fetch_16:
2390 caseBuiltin::BI__sync_val_compare_and_swap:
2391 caseBuiltin::BI__sync_val_compare_and_swap_1:
2392 caseBuiltin::BI__sync_val_compare_and_swap_2:
2393 caseBuiltin::BI__sync_val_compare_and_swap_4:
2394 caseBuiltin::BI__sync_val_compare_and_swap_8:
2395 caseBuiltin::BI__sync_val_compare_and_swap_16:
2396 caseBuiltin::BI__sync_bool_compare_and_swap:
2397 caseBuiltin::BI__sync_bool_compare_and_swap_1:
2398 caseBuiltin::BI__sync_bool_compare_and_swap_2:
2399 caseBuiltin::BI__sync_bool_compare_and_swap_4:
2400 caseBuiltin::BI__sync_bool_compare_and_swap_8:
2401 caseBuiltin::BI__sync_bool_compare_and_swap_16:
2402 caseBuiltin::BI__sync_lock_test_and_set:
2403 caseBuiltin::BI__sync_lock_test_and_set_1:
2404 caseBuiltin::BI__sync_lock_test_and_set_2:
2405 caseBuiltin::BI__sync_lock_test_and_set_4:
2406 caseBuiltin::BI__sync_lock_test_and_set_8:
2407 caseBuiltin::BI__sync_lock_test_and_set_16:
2408 caseBuiltin::BI__sync_lock_release:
2409 caseBuiltin::BI__sync_lock_release_1:
2410 caseBuiltin::BI__sync_lock_release_2:
2411 caseBuiltin::BI__sync_lock_release_4:
2412 caseBuiltin::BI__sync_lock_release_8:
2413 caseBuiltin::BI__sync_lock_release_16:
2414 caseBuiltin::BI__sync_swap:
2415 caseBuiltin::BI__sync_swap_1:
2416 caseBuiltin::BI__sync_swap_2:
2417 caseBuiltin::BI__sync_swap_4:
2418 caseBuiltin::BI__sync_swap_8:
2419 caseBuiltin::BI__sync_swap_16:
2420 returnBuiltinAtomicOverloaded(TheCallResult);
2421 caseBuiltin::BI__sync_synchronize:
2425 caseBuiltin::BI__builtin_nontemporal_load:
2426 caseBuiltin::BI__builtin_nontemporal_store:
2427 returnBuiltinNontemporalOverloaded(TheCallResult);
2428 caseBuiltin::BI__builtin_memcpy_inline: {
2441 caseBuiltin::BI__builtin_memset_inline: {
2452#define BUILTIN(ID, TYPE, ATTRS) 2453#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 2454 case Builtin::BI##ID: \ 2455 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); 2456#include "clang/Basic/Builtins.inc" 2457 caseBuiltin::BI__annotation:
2461 caseBuiltin::BI__builtin_annotation:
2465 caseBuiltin::BI__builtin_addressof:
2469 caseBuiltin::BI__builtin_function_start:
2473 caseBuiltin::BI__builtin_is_aligned:
2474 caseBuiltin::BI__builtin_align_up:
2475 caseBuiltin::BI__builtin_align_down:
2479 caseBuiltin::BI__builtin_add_overflow:
2480 caseBuiltin::BI__builtin_sub_overflow:
2481 caseBuiltin::BI__builtin_mul_overflow:
2485 caseBuiltin::BI__builtin_operator_new:
2486 caseBuiltin::BI__builtin_operator_delete: {
2487 boolIsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2489BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2494 caseBuiltin::BI__builtin_dump_struct:
2496 caseBuiltin::BI__builtin_expect_with_probability: {
2504Eval.
Diag= &Notes;
2507 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2513llvm::APFloat Probability = Eval.
Val.
getFloat();
2514 boolLoseInfo =
false;
2515Probability.convert(llvm::APFloat::IEEEdouble(),
2516llvm::RoundingMode::Dynamic, &LoseInfo);
2517 if(!(Probability >= llvm::APFloat(0.0) &&
2518Probability <= llvm::APFloat(1.0))) {
2525 caseBuiltin::BI__builtin_preserve_access_index:
2529 caseBuiltin::BI__builtin_call_with_static_chain:
2533 caseBuiltin::BI__exception_code:
2534 caseBuiltin::BI_exception_code:
2536diag::err_seh___except_block))
2539 caseBuiltin::BI__exception_info:
2540 caseBuiltin::BI_exception_info:
2542diag::err_seh___except_filter))
2545 caseBuiltin::BI__GetExceptionInfo:
2557 caseBuiltin::BIaddressof:
2558 caseBuiltin::BI__addressof:
2559 caseBuiltin::BIforward:
2560 caseBuiltin::BIforward_like:
2561 caseBuiltin::BImove:
2562 caseBuiltin::BImove_if_noexcept:
2563 caseBuiltin::BIas_const: {
2571 boolReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2572BuiltinID == Builtin::BI__addressof;
2574(ReturnsPointer ?
Result->isAnyPointerType()
2575:
Result->isReferenceType()) &&
2577 Result->getPointeeType()))) {
2578 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2584 caseBuiltin::BI__builtin_ptrauth_strip:
2586 caseBuiltin::BI__builtin_ptrauth_blend_discriminator:
2588 caseBuiltin::BI__builtin_ptrauth_sign_constant:
2591 caseBuiltin::BI__builtin_ptrauth_sign_unauthenticated:
2594 caseBuiltin::BI__builtin_ptrauth_auth:
2597 caseBuiltin::BI__builtin_ptrauth_sign_generic_data:
2599 caseBuiltin::BI__builtin_ptrauth_auth_and_resign:
2601 caseBuiltin::BI__builtin_ptrauth_string_discriminator:
2604 caseBuiltin::BIread_pipe:
2605 caseBuiltin::BIwrite_pipe:
2608 if(
OpenCL().checkBuiltinRWPipe(TheCall))
2611 caseBuiltin::BIreserve_read_pipe:
2612 caseBuiltin::BIreserve_write_pipe:
2613 caseBuiltin::BIwork_group_reserve_read_pipe:
2614 caseBuiltin::BIwork_group_reserve_write_pipe:
2615 if(
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2618 caseBuiltin::BIsub_group_reserve_read_pipe:
2619 caseBuiltin::BIsub_group_reserve_write_pipe:
2620 if(
OpenCL().checkSubgroupExt(TheCall) ||
2621 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2624 caseBuiltin::BIcommit_read_pipe:
2625 caseBuiltin::BIcommit_write_pipe:
2626 caseBuiltin::BIwork_group_commit_read_pipe:
2627 caseBuiltin::BIwork_group_commit_write_pipe:
2628 if(
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2631 caseBuiltin::BIsub_group_commit_read_pipe:
2632 caseBuiltin::BIsub_group_commit_write_pipe:
2633 if(
OpenCL().checkSubgroupExt(TheCall) ||
2634 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2637 caseBuiltin::BIget_pipe_num_packets:
2638 caseBuiltin::BIget_pipe_max_packets:
2639 if(
OpenCL().checkBuiltinPipePackets(TheCall))
2642 caseBuiltin::BIto_global:
2643 caseBuiltin::BIto_local:
2644 caseBuiltin::BIto_private:
2645 if(
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2649 caseBuiltin::BIenqueue_kernel:
2650 if(
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2653 caseBuiltin::BIget_kernel_work_group_size:
2654 caseBuiltin::BIget_kernel_preferred_work_group_size_multiple:
2655 if(
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2658 caseBuiltin::BIget_kernel_max_sub_group_size_for_ndrange:
2659 caseBuiltin::BIget_kernel_sub_group_count_for_ndrange:
2660 if(
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2663 caseBuiltin::BI__builtin_os_log_format:
2666 caseBuiltin::BI__builtin_os_log_format_buffer_size:
2667 if(BuiltinOSLogFormat(TheCall))
2670 caseBuiltin::BI__builtin_frame_address:
2671 caseBuiltin::BI__builtin_return_address: {
2680 Result.Val.getInt() != 0)
2682<< ((BuiltinID == Builtin::BI__builtin_return_address)
2683?
"__builtin_return_address" 2684:
"__builtin_frame_address")
2689 caseBuiltin::BI__builtin_nondeterministic_value: {
2690 if(BuiltinNonDeterministicValue(TheCall))
2697 caseBuiltin::BI__builtin_elementwise_abs: {
2705EltTy = VecTy->getElementType();
2708diag::err_builtin_invalid_arg_type)
2717 caseBuiltin::BI__builtin_elementwise_acos:
2718 caseBuiltin::BI__builtin_elementwise_asin:
2719 caseBuiltin::BI__builtin_elementwise_atan:
2720 caseBuiltin::BI__builtin_elementwise_ceil:
2721 caseBuiltin::BI__builtin_elementwise_cos:
2722 caseBuiltin::BI__builtin_elementwise_cosh:
2723 caseBuiltin::BI__builtin_elementwise_exp:
2724 caseBuiltin::BI__builtin_elementwise_exp2:
2725 caseBuiltin::BI__builtin_elementwise_floor:
2726 caseBuiltin::BI__builtin_elementwise_log:
2727 caseBuiltin::BI__builtin_elementwise_log2:
2728 caseBuiltin::BI__builtin_elementwise_log10:
2729 caseBuiltin::BI__builtin_elementwise_roundeven:
2730 caseBuiltin::BI__builtin_elementwise_round:
2731 caseBuiltin::BI__builtin_elementwise_rint:
2732 caseBuiltin::BI__builtin_elementwise_nearbyint:
2733 caseBuiltin::BI__builtin_elementwise_sin:
2734 caseBuiltin::BI__builtin_elementwise_sinh:
2735 caseBuiltin::BI__builtin_elementwise_sqrt:
2736 caseBuiltin::BI__builtin_elementwise_tan:
2737 caseBuiltin::BI__builtin_elementwise_tanh:
2738 caseBuiltin::BI__builtin_elementwise_trunc:
2739 caseBuiltin::BI__builtin_elementwise_canonicalize: {
2749 caseBuiltin::BI__builtin_elementwise_fma: {
2757 caseBuiltin::BI__builtin_elementwise_minimum:
2758 caseBuiltin::BI__builtin_elementwise_maximum:
2759 caseBuiltin::BI__builtin_elementwise_atan2:
2760 caseBuiltin::BI__builtin_elementwise_fmod:
2761 caseBuiltin::BI__builtin_elementwise_pow: {
2762 if(BuiltinElementwiseMath(TheCall,
true))
2769 caseBuiltin::BI__builtin_elementwise_add_sat:
2770 caseBuiltin::BI__builtin_elementwise_sub_sat: {
2771 if(BuiltinElementwiseMath(TheCall))
2779EltTy = VecTy->getElementType();
2789 caseBuiltin::BI__builtin_elementwise_min:
2790 caseBuiltin::BI__builtin_elementwise_max:
2791 if(BuiltinElementwiseMath(TheCall))
2794 caseBuiltin::BI__builtin_elementwise_popcount:
2795 caseBuiltin::BI__builtin_elementwise_bitreverse: {
2804EltTy = VecTy->getElementType();
2814 caseBuiltin::BI__builtin_elementwise_copysign: {
2834diag::err_typecheck_call_different_arg_types)
2835<< MagnitudeTy << SignTy;
2838TheCall->
setArg(0, Magnitude.
get());
2843 caseBuiltin::BI__builtin_reduce_max:
2844 caseBuiltin::BI__builtin_reduce_min: {
2845 if(PrepareBuiltinReduceMathOneArgCall(TheCall))
2853ElTy = TyA->getElementType();
2857 if(ElTy.isNull()) {
2859<< 1 <<
4 << Arg->
getType();
2866 caseBuiltin::BI__builtin_reduce_maximum:
2867 caseBuiltin::BI__builtin_reduce_minimum: {
2868 if(PrepareBuiltinReduceMathOneArgCall(TheCall))
2876ElTy = TyA->getElementType();
2880 if(ElTy.isNull() || !ElTy->isFloatingType()) {
2882<< 1 <<
9 << Arg->
getType();
2892 caseBuiltin::BI__builtin_reduce_add:
2893 caseBuiltin::BI__builtin_reduce_mul:
2894 caseBuiltin::BI__builtin_reduce_xor:
2895 caseBuiltin::BI__builtin_reduce_or:
2896 caseBuiltin::BI__builtin_reduce_and: {
2897 if(PrepareBuiltinReduceMathOneArgCall(TheCall))
2905ElTy = TyA->getElementType();
2909 if(ElTy.isNull() || !ElTy->isIntegerType()) {
2911<< 1 <<
6 << Arg->
getType();
2919 caseBuiltin::BI__builtin_matrix_transpose:
2920 returnBuiltinMatrixTranspose(TheCall, TheCallResult);
2922 caseBuiltin::BI__builtin_matrix_column_major_load:
2923 returnBuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2925 caseBuiltin::BI__builtin_matrix_column_major_store:
2926 returnBuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2928 caseBuiltin::BI__builtin_verbose_trap:
2933 caseBuiltin::BI__builtin_get_device_side_mangled_name: {
2934 autoCheck = [](
CallExpr*TheCall) {
2940 auto*
D= DRE->getDecl();
2941 if(!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2943 return D->
hasAttr<CUDAGlobalAttr>() ||
D->
hasAttr<CUDADeviceAttr>() ||
2946 if(!Check(TheCall)) {
2948diag::err_hip_invalid_args_builtin_mangled_name);
2953 caseBuiltin::BI__builtin_popcountg:
2957 caseBuiltin::BI__builtin_clzg:
2958 caseBuiltin::BI__builtin_ctzg:
2963 caseBuiltin::BI__builtin_allow_runtime_check: {
2973 caseBuiltin::BI__builtin_counted_by_ref:
2974 if(BuiltinCountedByRef(TheCall))
2987 "Aux Target Builtin, but not an aux target?");
2989 if(CheckTSBuiltinFunctionCall(
3000 returnTheCallResult;
3015 if(
Result.isShiftedMask() || (~
Result).isShiftedMask())
3019diag::err_argument_not_contiguous_bit_field)
3025 if(Format->getFirstArg() == 0)
3027 else if(IsVariadic)
3031FSI->
FormatIdx= Format->getFormatIdx() - 1;
3055 if(isa<CXXNullPtrLiteralExpr>(
3070 if(
const auto*CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3071 if(
const auto*ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3072 Expr= ILE->getInit(0);
3082 const Expr*ArgExpr,
3086S.
PDiag(diag::warn_null_arg)
3092 if(
autonullability =
type->getNullability())
3103assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3109llvm::SmallBitVector NonNullArgs;
3113 if(!
NonNull->args_size()) {
3115 for(
const auto*Arg : Args)
3122 unsignedIdxAST = Idx.getASTIndex();
3123 if(IdxAST >= Args.size())
3125 if(NonNullArgs.empty())
3126NonNullArgs.resize(Args.size());
3127NonNullArgs.set(IdxAST);
3132 if(FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3136 if(
const FunctionDecl*FD = dyn_cast<FunctionDecl>(FDecl))
3139parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3141 unsignedParamIndex = 0;
3143I !=
E; ++I, ++ParamIndex) {
3146 if(NonNullArgs.empty())
3147NonNullArgs.resize(Args.size());
3149NonNullArgs.set(ParamIndex);
3156 if(
const ValueDecl*VD = dyn_cast<ValueDecl>(FDecl)) {
3161 type= blockType->getPointeeType();
3175 if(NonNullArgs.empty())
3176NonNullArgs.resize(Args.size());
3178NonNullArgs.set(Index);
3187 for(
unsignedArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3188ArgIndex != ArgIndexEnd; ++ArgIndex) {
3189 if(NonNullArgs[ArgIndex])
3195StringRef ParamName,
QualTypeArgTy,
3223 if(ArgAlign < ParamAlign)
3224 Diag(
Loc, diag::warn_param_mismatched_alignment)
3226<< ParamName << (FDecl !=
nullptr) << FDecl;
3230 const Expr*ThisArg,
3232 if(!FD || Args.empty())
3234 autoGetArgAt = [&](
intIdx) ->
const Expr* {
3235 if(Idx == LifetimeCaptureByAttr::GLOBAL ||
3236Idx == LifetimeCaptureByAttr::UNKNOWN)
3238 if(IsMemberFunction && Idx == 0)
3240 returnArgs[Idx - IsMemberFunction];
3242 autoHandleCaptureByAttr = [&](
constLifetimeCaptureByAttr *
Attr,
3247 Expr*Captured =
const_cast<Expr*
>(GetArgAt(ArgIdx));
3248 for(
intCapturingParamIdx :
Attr->params()) {
3251 if(CapturingParamIdx == LifetimeCaptureByAttr::THIS &&
3252isa<CXXConstructorDecl>(FD))
3254 Expr*Capturing =
const_cast<Expr*
>(GetArgAt(CapturingParamIdx));
3262I + IsMemberFunction);
3264 if(IsMemberFunction) {
3272HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3285llvm::SmallBitVector CheckedVarArgs;
3289CheckedVarArgs.resize(Args.size());
3291CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3298 auto*FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3302: isa_and_nonnull<FunctionDecl>(FDecl)
3303? cast<FunctionDecl>(FDecl)->getNumParams()
3304: isa_and_nonnull<ObjCMethodDecl>(FDecl)
3305? cast<ObjCMethodDecl>(FDecl)->param_size()
3308 for(
unsignedArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3310 if(
const Expr*Arg = Args[ArgIdx]) {
3311 if(CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3318 if(FDecl || Proto) {
3323 for(
const auto*I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3324CheckArgumentWithTypeTag(I, Args,
Loc);
3330 if(!Proto && FDecl) {
3332 if(isa_and_nonnull<FunctionProtoType>(FT))
3338 const autoN = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3340 boolIsScalableArg =
false;
3341 for(
unsignedArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3343 if(
const Expr*Arg = Args[ArgIdx]) {
3355IsScalableArg =
true;
3357CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3366 if(
auto*CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3367llvm::StringMap<bool> CallerFeatureMap;
3369 if(!CallerFeatureMap.contains(
"sme"))
3370 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3372 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3379 const auto*CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3381(IsScalableArg || IsScalableRet)) {
3382 boolIsCalleeStreaming =
3384 boolIsCalleeStreamingCompatible =
3388 if(!IsCalleeStreamingCompatible &&
3392 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3395 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3406 boolCallerHasZAState =
false;
3407 boolCallerHasZT0State =
false;
3409 auto*
Attr= CallerFD->getAttr<ArmNewAttr>();
3411CallerHasZAState =
true;
3413CallerHasZT0State =
true;
3417FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3419CallerHasZT0State |=
3421FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3427 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3430 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3434 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3435 Diag(
Loc, diag::note_sme_use_preserves_za);
3440 if(FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3441 auto*AA = FDecl->
getAttr<AllocAlignAttr>();
3442 const Expr*Arg = Args[AA->getParamIndex().getASTIndex()];
3443 if(!Arg->isValueDependent()) {
3445 if(Arg->EvaluateAsInt(Align,
Context)) {
3446 constllvm::APSInt &I = Align.
Val.
getInt();
3447 if(!I.isPowerOf2())
3448 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3449<< Arg->getSourceRange();
3452 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3475 auto*Ctor = cast<CXXConstructorDecl>(FDecl);
3480 checkCall(FDecl, Proto,
nullptr, Args,
true,
3486 boolIsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3487isa<CXXMethodDecl>(FDecl);
3488 boolIsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3489IsMemberOperatorCall;
3495 Expr*ImplicitThis =
nullptr;
3500ImplicitThis = Args[0];
3503}
else if(IsMemberFunction && !FDecl->
isStatic() &&
3506cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3518cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3520CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3538CheckAbsoluteValueFunction(TheCall, FDecl);
3539CheckMaxUnsignedZero(TheCall, FDecl);
3540CheckInfNaNFunction(TheCall, FDecl);
3551 caseBuiltin::BIstrlcpy:
3552 caseBuiltin::BIstrlcat:
3553CheckStrlcpycatArguments(TheCall, FnInfo);
3555 caseBuiltin::BIstrncat:
3556CheckStrncatArguments(TheCall, FnInfo);
3558 caseBuiltin::BIfree:
3559CheckFreeArguments(TheCall);
3562CheckMemaccessArguments(TheCall, CMId, FnInfo);
3571 if(
const auto*
V= dyn_cast<VarDecl>(NDecl))
3572Ty =
V->getType().getNonReferenceType();
3573 else if(
const auto*F = dyn_cast<FieldDecl>(NDecl))
3574Ty = F->getType().getNonReferenceType();
3611 if(!llvm::isValidAtomicOrderingCABI(Ordering))
3614 autoOrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3616 caseAtomicExpr::AO__c11_atomic_init:
3617 caseAtomicExpr::AO__opencl_atomic_init:
3618llvm_unreachable(
"There is no ordering argument for an init");
3620 caseAtomicExpr::AO__c11_atomic_load:
3621 caseAtomicExpr::AO__opencl_atomic_load:
3622 caseAtomicExpr::AO__hip_atomic_load:
3623 caseAtomicExpr::AO__atomic_load_n:
3624 caseAtomicExpr::AO__atomic_load:
3625 caseAtomicExpr::AO__scoped_atomic_load_n:
3626 caseAtomicExpr::AO__scoped_atomic_load:
3627 returnOrderingCABI != llvm::AtomicOrderingCABI::release &&
3628OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3630 caseAtomicExpr::AO__c11_atomic_store:
3631 caseAtomicExpr::AO__opencl_atomic_store:
3632 caseAtomicExpr::AO__hip_atomic_store:
3633 caseAtomicExpr::AO__atomic_store:
3634 caseAtomicExpr::AO__atomic_store_n:
3635 caseAtomicExpr::AO__scoped_atomic_store:
3636 caseAtomicExpr::AO__scoped_atomic_store_n:
3637 caseAtomicExpr::AO__atomic_clear:
3638 returnOrderingCABI != llvm::AtomicOrderingCABI::consume &&
3639OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3640OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3649 CallExpr*TheCall = cast<CallExpr>(TheCallResult.
get());
3699 const unsignedNumForm = ClearByte + 1;
3700 const unsignedNumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
3701 const unsignedNumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
3709 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3710&&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3711 "need to update code for modified forms");
3712 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3713AtomicExpr::AO__atomic_xor_fetch + 1 ==
3714AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3715 "need to update code for modified C11 atomics");
3716 boolIsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3717Op <= AtomicExpr::AO__opencl_atomic_store;
3718 boolIsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3719Op <= AtomicExpr::AO__hip_atomic_store;
3720 boolIsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3721Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3722 boolIsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3723Op <= AtomicExpr::AO__c11_atomic_store) ||
3725 boolIsN = Op == AtomicExpr::AO__atomic_load_n ||
3726Op == AtomicExpr::AO__atomic_store_n ||
3727Op == AtomicExpr::AO__atomic_exchange_n ||
3728Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3729Op == AtomicExpr::AO__scoped_atomic_load_n ||
3730Op == AtomicExpr::AO__scoped_atomic_store_n ||
3731Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3732Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3736 enumArithOpExtraValueType {
3741 unsignedArithAllows = AOEVT_None;
3744 caseAtomicExpr::AO__c11_atomic_init:
3745 caseAtomicExpr::AO__opencl_atomic_init:
3749 caseAtomicExpr::AO__c11_atomic_load:
3750 caseAtomicExpr::AO__opencl_atomic_load:
3751 caseAtomicExpr::AO__hip_atomic_load:
3752 caseAtomicExpr::AO__atomic_load_n:
3753 caseAtomicExpr::AO__scoped_atomic_load_n:
3757 caseAtomicExpr::AO__atomic_load:
3758 caseAtomicExpr::AO__scoped_atomic_load:
3762 caseAtomicExpr::AO__c11_atomic_store:
3763 caseAtomicExpr::AO__opencl_atomic_store:
3764 caseAtomicExpr::AO__hip_atomic_store:
3765 caseAtomicExpr::AO__atomic_store:
3766 caseAtomicExpr::AO__atomic_store_n:
3767 caseAtomicExpr::AO__scoped_atomic_store:
3768 caseAtomicExpr::AO__scoped_atomic_store_n:
3771 caseAtomicExpr::AO__atomic_fetch_add:
3772 caseAtomicExpr::AO__atomic_fetch_sub:
3773 caseAtomicExpr::AO__atomic_add_fetch:
3774 caseAtomicExpr::AO__atomic_sub_fetch:
3775 caseAtomicExpr::AO__scoped_atomic_fetch_add:
3776 caseAtomicExpr::AO__scoped_atomic_fetch_sub:
3777 caseAtomicExpr::AO__scoped_atomic_add_fetch:
3778 caseAtomicExpr::AO__scoped_atomic_sub_fetch:
3779 caseAtomicExpr::AO__c11_atomic_fetch_add:
3780 caseAtomicExpr::AO__c11_atomic_fetch_sub:
3781 caseAtomicExpr::AO__opencl_atomic_fetch_add:
3782 caseAtomicExpr::AO__opencl_atomic_fetch_sub:
3783 caseAtomicExpr::AO__hip_atomic_fetch_add:
3784 caseAtomicExpr::AO__hip_atomic_fetch_sub:
3785ArithAllows = AOEVT_Pointer | AOEVT_FP;
3788 caseAtomicExpr::AO__atomic_fetch_max:
3789 caseAtomicExpr::AO__atomic_fetch_min:
3790 caseAtomicExpr::AO__atomic_max_fetch:
3791 caseAtomicExpr::AO__atomic_min_fetch:
3792 caseAtomicExpr::AO__scoped_atomic_fetch_max:
3793 caseAtomicExpr::AO__scoped_atomic_fetch_min:
3794 caseAtomicExpr::AO__scoped_atomic_max_fetch:
3795 caseAtomicExpr::AO__scoped_atomic_min_fetch:
3796 caseAtomicExpr::AO__c11_atomic_fetch_max:
3797 caseAtomicExpr::AO__c11_atomic_fetch_min:
3798 caseAtomicExpr::AO__opencl_atomic_fetch_max:
3799 caseAtomicExpr::AO__opencl_atomic_fetch_min:
3800 caseAtomicExpr::AO__hip_atomic_fetch_max:
3801 caseAtomicExpr::AO__hip_atomic_fetch_min:
3802ArithAllows = AOEVT_FP;
3805 caseAtomicExpr::AO__c11_atomic_fetch_and:
3806 caseAtomicExpr::AO__c11_atomic_fetch_or:
3807 caseAtomicExpr::AO__c11_atomic_fetch_xor:
3808 caseAtomicExpr::AO__hip_atomic_fetch_and:
3809 caseAtomicExpr::AO__hip_atomic_fetch_or:
3810 caseAtomicExpr::AO__hip_atomic_fetch_xor:
3811 caseAtomicExpr::AO__c11_atomic_fetch_nand:
3812 caseAtomicExpr::AO__opencl_atomic_fetch_and:
3813 caseAtomicExpr::AO__opencl_atomic_fetch_or:
3814 caseAtomicExpr::AO__opencl_atomic_fetch_xor:
3815 caseAtomicExpr::AO__atomic_fetch_and:
3816 caseAtomicExpr::AO__atomic_fetch_or:
3817 caseAtomicExpr::AO__atomic_fetch_xor:
3818 caseAtomicExpr::AO__atomic_fetch_nand:
3819 caseAtomicExpr::AO__atomic_and_fetch:
3820 caseAtomicExpr::AO__atomic_or_fetch:
3821 caseAtomicExpr::AO__atomic_xor_fetch:
3822 caseAtomicExpr::AO__atomic_nand_fetch:
3823 caseAtomicExpr::AO__scoped_atomic_fetch_and:
3824 caseAtomicExpr::AO__scoped_atomic_fetch_or:
3825 caseAtomicExpr::AO__scoped_atomic_fetch_xor:
3826 caseAtomicExpr::AO__scoped_atomic_fetch_nand:
3827 caseAtomicExpr::AO__scoped_atomic_and_fetch:
3828 caseAtomicExpr::AO__scoped_atomic_or_fetch:
3829 caseAtomicExpr::AO__scoped_atomic_xor_fetch:
3830 caseAtomicExpr::AO__scoped_atomic_nand_fetch:
3834 caseAtomicExpr::AO__c11_atomic_exchange:
3835 caseAtomicExpr::AO__hip_atomic_exchange:
3836 caseAtomicExpr::AO__opencl_atomic_exchange:
3837 caseAtomicExpr::AO__atomic_exchange_n:
3838 caseAtomicExpr::AO__scoped_atomic_exchange_n:
3842 caseAtomicExpr::AO__atomic_exchange:
3843 caseAtomicExpr::AO__scoped_atomic_exchange:
3847 caseAtomicExpr::AO__c11_atomic_compare_exchange_strong:
3848 caseAtomicExpr::AO__c11_atomic_compare_exchange_weak:
3849 caseAtomicExpr::AO__hip_atomic_compare_exchange_strong:
3850 caseAtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3851 caseAtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3852 caseAtomicExpr::AO__hip_atomic_compare_exchange_weak:
3856 caseAtomicExpr::AO__atomic_compare_exchange:
3857 caseAtomicExpr::AO__atomic_compare_exchange_n:
3858 caseAtomicExpr::AO__scoped_atomic_compare_exchange:
3859 caseAtomicExpr::AO__scoped_atomic_compare_exchange_n:
3863 caseAtomicExpr::AO__atomic_test_and_set:
3864Form = TestAndSetByte;
3867 caseAtomicExpr::AO__atomic_clear:
3872 unsignedAdjustedNumArgs = NumArgs[Form];
3873 if((IsOpenCL || IsHIP || IsScoped) &&
3874Op != AtomicExpr::AO__opencl_atomic_init)
3877 if(Args.size() < AdjustedNumArgs) {
3878 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3879<< 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3882}
else if(Args.size() > AdjustedNumArgs) {
3883 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3884diag::err_typecheck_call_too_many_args)
3885<< 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3891 Expr*Ptr = Args[0];
3896Ptr = ConvertedPtr.
get();
3899 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3909 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3915 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3921}
else if(Form != Load && Form != LoadCopy) {
3923 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3929 if(Form != TestAndSetByte && Form != ClearByte) {
3932diag::err_incomplete_type))
3936 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3946 pointerType->getPointeeType().getCVRQualifiers());
3954 if(Form == Arithmetic) {
3957 autoIsAllowedValueType = [&](
QualTypeValType,
3958 unsignedAllowedType) ->
bool{
3962 returnAllowedType & AOEVT_Pointer;
3968&llvm::APFloat::x87DoubleExtended())
3972 if(!IsAllowedValueType(ValType, ArithAllows)) {
3973 autoDID = ArithAllows & AOEVT_FP
3974? (ArithAllows & AOEVT_Pointer
3975? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3976: diag::err_atomic_op_needs_atomic_int_or_fp)
3977: diag::err_atomic_op_needs_atomic_int;
3984diag::err_incomplete_type)) {
3990 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4001 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4017 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4029 if(Form ==
Copy|| Form == LoadCopy || Form == GNUXchg || Form ==
Init||
4032 else if(Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4038 boolIsPassedByAddress =
false;
4039 if(!IsC11 && !IsHIP && !IsN) {
4041IsPassedByAddress =
true;
4046APIOrderedArgs.push_back(Args[0]);
4050APIOrderedArgs.push_back(Args[1]);
4056APIOrderedArgs.push_back(Args[2]);
4057APIOrderedArgs.push_back(Args[1]);
4060APIOrderedArgs.push_back(Args[2]);
4061APIOrderedArgs.push_back(Args[3]);
4062APIOrderedArgs.push_back(Args[1]);
4065APIOrderedArgs.push_back(Args[2]);
4066APIOrderedArgs.push_back(Args[4]);
4067APIOrderedArgs.push_back(Args[1]);
4068APIOrderedArgs.push_back(Args[3]);
4071APIOrderedArgs.push_back(Args[2]);
4072APIOrderedArgs.push_back(Args[4]);
4073APIOrderedArgs.push_back(Args[5]);
4074APIOrderedArgs.push_back(Args[1]);
4075APIOrderedArgs.push_back(Args[3]);
4077 caseTestAndSetByte:
4079APIOrderedArgs.push_back(Args[1]);
4083APIOrderedArgs.append(Args.begin(), Args.end());
4090 for(
unsignedi = 0; i != APIOrderedArgs.size(); ++i) {
4092 if(i < NumVals[Form] + 1) {
4105assert(Form != Load);
4108 else if(Form ==
Init|| Form == Arithmetic)
4110 else if(Form ==
Copy|| Form == Xchg) {
4111 if(IsPassedByAddress) {
4118 Expr*ValArg = APIOrderedArgs[i];
4125AS = PtrTy->getPointeeType().getAddressSpace();
4134 if(IsPassedByAddress)
4154APIOrderedArgs[i] = Arg.
get();
4159SubExprs.push_back(Ptr);
4163SubExprs.push_back(APIOrderedArgs[1]);
4166 caseTestAndSetByte:
4168SubExprs.push_back(APIOrderedArgs[1]);
4174SubExprs.push_back(APIOrderedArgs[2]);
4175SubExprs.push_back(APIOrderedArgs[1]);
4179SubExprs.push_back(APIOrderedArgs[3]);
4180SubExprs.push_back(APIOrderedArgs[1]);
4181SubExprs.push_back(APIOrderedArgs[2]);
4184SubExprs.push_back(APIOrderedArgs[3]);
4185SubExprs.push_back(APIOrderedArgs[1]);
4186SubExprs.push_back(APIOrderedArgs[4]);
4187SubExprs.push_back(APIOrderedArgs[2]);
4190SubExprs.push_back(APIOrderedArgs[4]);
4191SubExprs.push_back(APIOrderedArgs[1]);
4192SubExprs.push_back(APIOrderedArgs[5]);
4193SubExprs.push_back(APIOrderedArgs[2]);
4194SubExprs.push_back(APIOrderedArgs[3]);
4199 if(SubExprs.size() >= 2 && Form !=
Init) {
4200std::optional<llvm::APSInt>
Success=
4201SubExprs[1]->getIntegerConstantExpr(
Context);
4203 Diag(SubExprs[1]->getBeginLoc(),
4204diag::warn_atomic_op_has_invalid_memory_order)
4205<<
(Form == C11CmpXchg || Form == GNUCmpXchg)
4206<< SubExprs[1]->getSourceRange();
4208 if(SubExprs.size() >= 5) {
4209 if(std::optional<llvm::APSInt> Failure =
4210SubExprs[3]->getIntegerConstantExpr(
Context)) {
4211 if(!llvm::is_contained(
4212{llvm::AtomicOrderingCABI::relaxed,
4213llvm::AtomicOrderingCABI::consume,
4214llvm::AtomicOrderingCABI::acquire,
4215llvm::AtomicOrderingCABI::seq_cst},
4216(llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4217 Diag(SubExprs[3]->getBeginLoc(),
4218diag::warn_atomic_op_has_invalid_memory_order)
4219<<
2 << SubExprs[3]->getSourceRange();
4226 auto*
Scope= Args[Args.size() - 1];
4227 if(std::optional<llvm::APSInt>
Result=
4229 if(!ScopeModel->isValid(
Result->getZExtValue()))
4230 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4231<<
Scope->getSourceRange();
4233SubExprs.push_back(
Scope);
4239 if((Op == AtomicExpr::AO__c11_atomic_load ||
4240Op == AtomicExpr::AO__c11_atomic_store ||
4241Op == AtomicExpr::AO__opencl_atomic_load ||
4242Op == AtomicExpr::AO__hip_atomic_load ||
4243Op == AtomicExpr::AO__opencl_atomic_store ||
4244Op == AtomicExpr::AO__hip_atomic_store) &&
4247<< ((Op == AtomicExpr::AO__c11_atomic_load ||
4248Op == AtomicExpr::AO__opencl_atomic_load ||
4249Op == AtomicExpr::AO__hip_atomic_load)
4254 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4270assert(Fn &&
"builtin call without direct callee!");
4281 E->setArg(ArgIndex, Arg.
get());
4293 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4295<<
Callee->getSourceRange();
4308FirstArg = FirstArgResult.
get();
4309TheCall->
setArg(0, FirstArg);
4321 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4356#define BUILTIN_ROW(x) \ 4357 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ 4358 Builtin::BI##x##_8, Builtin::BI##x##_16 } 4360 static const unsignedBuiltinIndices[][5] = {
4386 case1: SizeIndex = 0;
break;
4387 case2: SizeIndex = 1;
break;
4388 case4: SizeIndex = 2;
break;
4389 case8: SizeIndex = 3;
break;
4390 case16: SizeIndex = 4;
break;
4402 unsignedBuiltinIndex, NumFixed = 1;
4403 boolWarnAboutSemanticsChange =
false;
4404 switch(BuiltinID) {
4405 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4406 caseBuiltin::BI__sync_fetch_and_add:
4407 caseBuiltin::BI__sync_fetch_and_add_1:
4408 caseBuiltin::BI__sync_fetch_and_add_2:
4409 caseBuiltin::BI__sync_fetch_and_add_4:
4410 caseBuiltin::BI__sync_fetch_and_add_8:
4411 caseBuiltin::BI__sync_fetch_and_add_16:
4415 caseBuiltin::BI__sync_fetch_and_sub:
4416 caseBuiltin::BI__sync_fetch_and_sub_1:
4417 caseBuiltin::BI__sync_fetch_and_sub_2:
4418 caseBuiltin::BI__sync_fetch_and_sub_4:
4419 caseBuiltin::BI__sync_fetch_and_sub_8:
4420 caseBuiltin::BI__sync_fetch_and_sub_16:
4424 caseBuiltin::BI__sync_fetch_and_or:
4425 caseBuiltin::BI__sync_fetch_and_or_1:
4426 caseBuiltin::BI__sync_fetch_and_or_2:
4427 caseBuiltin::BI__sync_fetch_and_or_4:
4428 caseBuiltin::BI__sync_fetch_and_or_8:
4429 caseBuiltin::BI__sync_fetch_and_or_16:
4433 caseBuiltin::BI__sync_fetch_and_and:
4434 caseBuiltin::BI__sync_fetch_and_and_1:
4435 caseBuiltin::BI__sync_fetch_and_and_2:
4436 caseBuiltin::BI__sync_fetch_and_and_4:
4437 caseBuiltin::BI__sync_fetch_and_and_8:
4438 caseBuiltin::BI__sync_fetch_and_and_16:
4442 caseBuiltin::BI__sync_fetch_and_xor:
4443 caseBuiltin::BI__sync_fetch_and_xor_1:
4444 caseBuiltin::BI__sync_fetch_and_xor_2:
4445 caseBuiltin::BI__sync_fetch_and_xor_4:
4446 caseBuiltin::BI__sync_fetch_and_xor_8:
4447 caseBuiltin::BI__sync_fetch_and_xor_16:
4451 caseBuiltin::BI__sync_fetch_and_nand:
4452 caseBuiltin::BI__sync_fetch_and_nand_1:
4453 caseBuiltin::BI__sync_fetch_and_nand_2:
4454 caseBuiltin::BI__sync_fetch_and_nand_4:
4455 caseBuiltin::BI__sync_fetch_and_nand_8:
4456 caseBuiltin::BI__sync_fetch_and_nand_16:
4458WarnAboutSemanticsChange =
true;
4461 caseBuiltin::BI__sync_add_and_fetch:
4462 caseBuiltin::BI__sync_add_and_fetch_1:
4463 caseBuiltin::BI__sync_add_and_fetch_2:
4464 caseBuiltin::BI__sync_add_and_fetch_4:
4465 caseBuiltin::BI__sync_add_and_fetch_8:
4466 caseBuiltin::BI__sync_add_and_fetch_16:
4470 caseBuiltin::BI__sync_sub_and_fetch:
4471 caseBuiltin::BI__sync_sub_and_fetch_1:
4472 caseBuiltin::BI__sync_sub_and_fetch_2:
4473 caseBuiltin::BI__sync_sub_and_fetch_4:
4474 caseBuiltin::BI__sync_sub_and_fetch_8:
4475 caseBuiltin::BI__sync_sub_and_fetch_16:
4479 caseBuiltin::BI__sync_and_and_fetch:
4480 caseBuiltin::BI__sync_and_and_fetch_1:
4481 caseBuiltin::BI__sync_and_and_fetch_2:
4482 caseBuiltin::BI__sync_and_and_fetch_4:
4483 caseBuiltin::BI__sync_and_and_fetch_8:
4484 caseBuiltin::BI__sync_and_and_fetch_16:
4488 caseBuiltin::BI__sync_or_and_fetch:
4489 caseBuiltin::BI__sync_or_and_fetch_1:
4490 caseBuiltin::BI__sync_or_and_fetch_2:
4491 caseBuiltin::BI__sync_or_and_fetch_4:
4492 caseBuiltin::BI__sync_or_and_fetch_8:
4493 caseBuiltin::BI__sync_or_and_fetch_16:
4497 caseBuiltin::BI__sync_xor_and_fetch:
4498 caseBuiltin::BI__sync_xor_and_fetch_1:
4499 caseBuiltin::BI__sync_xor_and_fetch_2:
4500 caseBuiltin::BI__sync_xor_and_fetch_4:
4501 caseBuiltin::BI__sync_xor_and_fetch_8:
4502 caseBuiltin::BI__sync_xor_and_fetch_16:
4506 caseBuiltin::BI__sync_nand_and_fetch:
4507 caseBuiltin::BI__sync_nand_and_fetch_1:
4508 caseBuiltin::BI__sync_nand_and_fetch_2:
4509 caseBuiltin::BI__sync_nand_and_fetch_4:
4510 caseBuiltin::BI__sync_nand_and_fetch_8:
4511 caseBuiltin::BI__sync_nand_and_fetch_16:
4513WarnAboutSemanticsChange =
true;
4516 caseBuiltin::BI__sync_val_compare_and_swap:
4517 caseBuiltin::BI__sync_val_compare_and_swap_1:
4518 caseBuiltin::BI__sync_val_compare_and_swap_2:
4519 caseBuiltin::BI__sync_val_compare_and_swap_4:
4520 caseBuiltin::BI__sync_val_compare_and_swap_8:
4521 caseBuiltin::BI__sync_val_compare_and_swap_16:
4526 caseBuiltin::BI__sync_bool_compare_and_swap:
4527 caseBuiltin::BI__sync_bool_compare_and_swap_1:
4528 caseBuiltin::BI__sync_bool_compare_and_swap_2:
4529 caseBuiltin::BI__sync_bool_compare_and_swap_4:
4530 caseBuiltin::BI__sync_bool_compare_and_swap_8:
4531 caseBuiltin::BI__sync_bool_compare_and_swap_16:
4537 caseBuiltin::BI__sync_lock_test_and_set:
4538 caseBuiltin::BI__sync_lock_test_and_set_1:
4539 caseBuiltin::BI__sync_lock_test_and_set_2:
4540 caseBuiltin::BI__sync_lock_test_and_set_4:
4541 caseBuiltin::BI__sync_lock_test_and_set_8:
4542 caseBuiltin::BI__sync_lock_test_and_set_16:
4546 caseBuiltin::BI__sync_lock_release:
4547 caseBuiltin::BI__sync_lock_release_1:
4548 caseBuiltin::BI__sync_lock_release_2:
4549 caseBuiltin::BI__sync_lock_release_4:
4550 caseBuiltin::BI__sync_lock_release_8:
4551 caseBuiltin::BI__sync_lock_release_16:
4557 caseBuiltin::BI__sync_swap:
4558 caseBuiltin::BI__sync_swap_1:
4559 caseBuiltin::BI__sync_swap_2:
4560 caseBuiltin::BI__sync_swap_4:
4561 caseBuiltin::BI__sync_swap_8:
4562 caseBuiltin::BI__sync_swap_16:
4570 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4571<< 0 << 1 + NumFixed << TheCall->
getNumArgs() <<
0
4572<<
Callee->getSourceRange();
4576 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4577<<
Callee->getSourceRange();
4579 if(WarnAboutSemanticsChange) {
4580 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4581<<
Callee->getSourceRange();
4586 unsignedNewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4589 if(NewBuiltinID == BuiltinID)
4590NewBuiltinDecl = FDecl;
4596assert(Res.getFoundDecl());
4597NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4598 if(!NewBuiltinDecl)
4605 for(
unsignedi = 0; i != NumFixed; ++i) {
4636CK_BuiltinFnToFnPtr);
4642TheCall->
setType(ResultType);
4648 if(BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4649 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4653 returnTheCallResult;
4662assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4663BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4664 "Unexpected nontemporal load/store builtin!");
4665 boolisStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4666 unsignednumArgs = isStore ? 2 : 1;
4676 Expr*PointerArg = TheCall->
getArg(numArgs - 1);
4682PointerArg = PointerArgResult.
get();
4683TheCall->
setArg(numArgs - 1, PointerArg);
4687 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4700diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4707 returnTheCallResult;
4719 returnTheCallResult;
4726 auto*
Literal= dyn_cast<StringLiteral>(Arg);
4728 if(
auto*ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4729 Literal= ObjcLiteral->getString();
4733 if(!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4735 Diag(Arg->
getBeginLoc(), diag::err_os_log_format_not_string_constant)
4751 boolIsX64 = TT.getArch() == llvm::Triple::x86_64;
4752 boolIsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4753TT.getArch() == llvm::Triple::aarch64_32);
4754 boolIsWindows = TT.isOSWindows();
4755 boolIsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4756 if(IsX64 || IsAArch64) {
4763 returnS.
Diag(Fn->getBeginLoc(),
4764diag::err_ms_va_start_used_in_sysv_function);
4772 returnS.
Diag(Fn->getBeginLoc(),
4773diag::err_va_start_used_in_wrong_abi_function)
4780 returnS.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4788 boolIsVariadic =
false;
4791 if(
auto*
Block= dyn_cast<BlockDecl>(Caller)) {
4792IsVariadic =
Block->isVariadic();
4793Params =
Block->parameters();
4794}
else if(
auto*FD = dyn_cast<FunctionDecl>(Caller)) {
4797}
else if(
auto*MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4798IsVariadic = MD->isVariadic();
4800Params = MD->parameters();
4801}
else if(isa<CapturedDecl>(Caller)) {
4803S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4807S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4812S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4817*LastParam = Params.empty() ? nullptr : Params.back();
4822boolSema::BuiltinVAStart(
unsignedBuiltinID,
CallExpr*TheCall) {
4847 boolSecondArgIsLastNamedArgument =
false;
4849 if(std::optional<llvm::APSInt> Val =
4858 boolIsCRegister =
false;
4860 if(
const DeclRefExpr*DR = dyn_cast<DeclRefExpr>(Arg)) {
4861 if(
const ParmVarDecl*PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4862SecondArgIsLastNamedArgument = PV == LastParam;
4864 Type= PV->getType();
4865ParamLoc = PV->getLocation();
4871 if(!SecondArgIsLastNamedArgument)
4873diag::warn_second_arg_of_va_start_not_last_named_param);
4878if (!Context.isPromotableIntegerType(Type))
4880if (!Type->isEnumeralType())
4882const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4884Context.typesAreCompatible(ED->getPromotionType(), Type));
4886 unsignedReason = 0;
4888 else if(IsCRegister) Reason = 2;
4889 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4890 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4896boolSema::BuiltinVAStartARMMicrosoft(
CallExpr*
Call) {
4897 autoIsSuitablyTypedFormatArgument = [
this](
const Expr*Arg) ->
bool{
4917 if(
Call->getNumArgs() < 3)
4919diag::err_typecheck_call_too_few_args_at_least)
4920<< 0
<< 3 <<
Call->getNumArgs()
4933 const Expr*Arg1 =
Call->getArg(1)->IgnoreParens();
4936 const Expr*Arg2 =
Call->getArg(2)->IgnoreParens();
4941 if(!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4942 Diag(Arg1->
getBeginLoc(), diag::err_typecheck_convert_incompatible)
4943<< Arg1->
getType() << ConstCharPtrTy << 1
4946<< 2 << Arg1->
getType() << ConstCharPtrTy;
4950 Diag(Arg2->
getBeginLoc(), diag::err_typecheck_convert_incompatible)
4951<< Arg2->
getType() << SizeTy << 1
4954<< 3 << Arg2->
getType() << SizeTy;
4959boolSema::BuiltinUnorderedCompare(
CallExpr*TheCall,
unsignedBuiltinID) {
4963 if(BuiltinID == Builtin::BI__builtin_isunordered &&
4991diag::err_typecheck_call_invalid_ordered_compare)
4999boolSema::BuiltinFPClassification(
CallExpr*TheCall,
unsignedNumArgs,
5000 unsignedBuiltinID) {
5005 if(FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5006BuiltinID == Builtin::BI__builtin_isinf ||
5007BuiltinID == Builtin::BI__builtin_isinf_sign))
5011 if(FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5012BuiltinID == Builtin::BI__builtin_isunordered))
5016 boolIsFPClass = NumArgs == 2;
5019 unsignedFPArgNo = IsFPClass ? 0 : NumArgs - 1;
5023 for(
unsignedi = 0; i < FPArgNo; ++i) {
5050OrigArg = Res.
get();
5056OrigArg = Res.
get();
5058TheCall->
setArg(FPArgNo, OrigArg);
5072diag::err_typecheck_call_invalid_unary_fp)
5084 if(!VectorResultTy.
isNull())
5085ResultTy = VectorResultTy;
5094boolSema::BuiltinComplex(
CallExpr*TheCall) {
5099 for(
unsignedI = 0; I != 2; ++I) {
5110 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5117TheCall->
setArg(I, Converted.
get());
5129diag::err_typecheck_call_different_arg_types)
5138 return Diag(TheCall->
getBeginLoc(), diag::err_invalid_complex_spec)
5141 return Diag(TheCall->
getBeginLoc(), diag::err_invalid_complex_spec)
5153diag::err_typecheck_call_too_few_args_at_least)
5161 unsignednumElements = 0;
5176 unsignednumResElements = TheCall->
getNumArgs() - 2;
5185diag::err_vec_builtin_incompatible_vector)
5192diag::err_vec_builtin_incompatible_vector)
5197}
else if(numElements != numResElements) {
5204 for(
unsignedi = 2; i < TheCall->
getNumArgs(); i++) {
5209std::optional<llvm::APSInt>
Result;
5212diag::err_shufflevector_nonconstant_argument)
5219 if(
Result->getActiveBits() > 64 ||
5220 Result->getZExtValue() >= numElements * 2)
5222diag::err_shufflevector_argument_too_large)
5228 for(
unsignedi = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5229exprs.push_back(TheCall->
getArg(i));
5230TheCall->
setArg(i,
nullptr);
5248diag::err_convertvector_non_vector)
5251 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5253<<
"__builtin_convertvector");
5258 if(SrcElts != DstElts)
5260diag::err_convertvector_incompatible_vector)
5265BuiltinLoc, RParenLoc);
5268boolSema::BuiltinPrefetch(
CallExpr*TheCall) {
5273diag::err_typecheck_call_too_many_args_at_most)
5274<< 0
<< 3 << NumArgs <<
0
5279 for(
unsignedi = 1; i != NumArgs; ++i)
5286boolSema::BuiltinArithmeticFence(
CallExpr*TheCall) {
5288 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5298 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5308boolSema::BuiltinAssume(
CallExpr*TheCall) {
5315<< cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5320boolSema::BuiltinAllocaWithAlign(
CallExpr*TheCall) {
5326 if(
const auto*UE =
5328 if(UE->getKind() == UETT_AlignOf ||
5329UE->getKind() == UETT_PreferredAlignOf)
5335 if(!
Result.isPowerOf2())
5336 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5343 if(
Result> std::numeric_limits<int32_t>::max())
5345<< std::numeric_limits<int32_t>::max() << Arg->
getSourceRange();
5351boolSema::BuiltinAssumeAligned(
CallExpr*TheCall) {
5362 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5366TheCall->
setArg(0, FirstArgResult.
get());
5378 if(!
Result.isPowerOf2())
5379 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5391TheCall->
setArg(2, ThirdArg);
5397boolSema::BuiltinOSLogFormat(
CallExpr*TheCall) {
5398 unsignedBuiltinID =
5399cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5400 boolIsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5403 unsignedNumRequiredArgs = IsSizeCall ? 1 : 2;
5404 if(NumArgs < NumRequiredArgs) {
5405 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5406<< 0
<< NumRequiredArgs << NumArgs
5409 if(NumArgs >= NumRequiredArgs + 0x100) {
5411diag::err_typecheck_call_too_many_args_at_most)
5412<< 0
<< (NumRequiredArgs + 0xff) << NumArgs
5423 if(Arg.isInvalid())
5425TheCall->
setArg(i, Arg.get());
5430 unsignedFormatIdx = i;
5440 unsignedFirstDataArg = i;
5441 while(i < NumArgs) {
5448 return Diag(Arg.
get()->
getEndLoc(), diag::err_os_log_argument_too_big)
5459llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5461 bool Success= CheckFormatArguments(
5478llvm::APSInt &
Result) {
5485std::optional<llvm::APSInt> R;
5487 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5494 intHigh,
boolRangeIsError) {
5508 if(
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5510 return Diag(TheCall->
getBeginLoc(), diag::err_argument_invalid_range)
5516 PDiag(diag::warn_argument_invalid_range)
5538 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_multiple)
5561 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5566 if(
Value.isNegative())
5577 if((
Value& 0xFF) != 0)
5602 Result.setIsUnsigned(
true);
5607 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5626 Result.setIsUnsigned(
true);
5634diag::err_argument_not_shifted_byte_or_xxff)
5638boolSema::BuiltinLongjmp(
CallExpr*TheCall) {
5640 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5651 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5657boolSema::BuiltinSetjmp(
CallExpr*TheCall) {
5659 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5664boolSema::BuiltinCountedByRef(
CallExpr*TheCall) {
5679diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5684diag::err_builtin_counted_by_ref_has_side_effects)
5687 if(
const auto*ME = dyn_cast<MemberExpr>(Arg)) {
5688 if(!ME->isFlexibleArrayMemberLike(
5691diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5697 const auto*FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
5705diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5715boolSema::CheckInvalidBuiltinCountedByRef(
const Expr*
E,
5716BuiltinCountedByRefKind K) {
5719 if(!CE || CE->
getBuiltinCallee() != Builtin::BI__builtin_counted_by_ref)
5723 caseAssignmentKind:
5724 caseInitializerKind:
5726diag::err_builtin_counted_by_ref_cannot_leak_reference)
5729 caseFunctionArgKind:
5731diag::err_builtin_counted_by_ref_cannot_leak_reference)
5736diag::err_builtin_counted_by_ref_cannot_leak_reference)
5739 caseArraySubscriptKind:
5740 Diag(
E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
5743 caseBinaryExprKind:
5744 Diag(
E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
5754classUncoveredArgHandler {
5755 enum{
Unknown= -1, AllCovered = -2 };
5757 signedFirstUncoveredArg =
Unknown;
5761UncoveredArgHandler() =
default;
5763 boolhasUncoveredArg()
const{
5764 return(FirstUncoveredArg >= 0);
5767 unsignedgetUncoveredArg()
const{
5768assert(hasUncoveredArg() &&
"no uncovered argument");
5769 returnFirstUncoveredArg;
5772 voidsetAllCovered() {
5775DiagnosticExprs.clear();
5776FirstUncoveredArg = AllCovered;
5779 void Update(
signedNewFirstUncoveredArg,
const Expr*StrExpr) {
5780assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5783 if(FirstUncoveredArg == AllCovered)
5788 if(NewFirstUncoveredArg == FirstUncoveredArg)
5789DiagnosticExprs.push_back(StrExpr);
5790 else if(NewFirstUncoveredArg > FirstUncoveredArg) {
5791DiagnosticExprs.clear();
5792DiagnosticExprs.push_back(StrExpr);
5793FirstUncoveredArg = NewFirstUncoveredArg;
5797 voidDiagnose(
Sema&S,
boolIsFunctionCall,
const Expr*ArgExpr);
5800enumStringLiteralCheckType {
5802SLCT_UncheckedLiteral,
5808static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend,
5810 boolAddendIsRight) {
5811 unsignedBitWidth = Offset.getBitWidth();
5812 unsignedAddendBitWidth = Addend.getBitWidth();
5814 if(Addend.isUnsigned()) {
5815Addend = Addend.zext(++AddendBitWidth);
5816Addend.setIsSigned(
true);
5819 if(AddendBitWidth > BitWidth) {
5820Offset = Offset.sext(AddendBitWidth);
5821BitWidth = AddendBitWidth;
5822}
else if(BitWidth > AddendBitWidth) {
5823Addend = Addend.sext(BitWidth);
5827llvm::APSInt ResOffset = Offset;
5828 if(BinOpKind == BO_Add)
5829ResOffset = Offset.sadd_ov(Addend, Ov);
5831assert(AddendIsRight && BinOpKind == BO_Sub &&
5832 "operator must be add or sub with addend on the right");
5833ResOffset = Offset.ssub_ov(Addend, Ov);
5839assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5840 "index (intermediate) result too big");
5841Offset = Offset.sext(2 * BitWidth);
5842 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5854classFormatStringLiteral {
5859FormatStringLiteral(
const StringLiteral*fexpr, int64_t Offset = 0)
5860: FExpr(fexpr), Offset(Offset) {}
5862StringRef getString()
const{
5863 returnFExpr->
getString().drop_front(Offset);
5866 unsignedgetByteLength()
const{
5867 returnFExpr->
getByteLength() - getCharByteWidth() * Offset;
5870 unsignedgetLength()
const{
returnFExpr->
getLength() - Offset; }
5877 boolisAscii()
const{
returnFExpr->
isOrdinary(); }
5878 boolisWide()
const{
returnFExpr->
isWide(); }
5879 boolisUTF8()
const{
returnFExpr->
isUTF8(); }
5880 boolisUTF16()
const{
returnFExpr->
isUTF16(); }
5881 boolisUTF32()
const{
returnFExpr->
isUTF32(); }
5882 boolisPascal()
const{
returnFExpr->
isPascal(); }
5887 unsigned*StartTokenByteOffset =
nullptr)
const{
5889StartToken, StartTokenByteOffset);
5902 Sema&S,
constFormatStringLiteral *FExpr,
const Expr*OrigFormatExpr,
5906llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5907 boolIgnoreStringsWithoutSpecifiers);
5916staticStringLiteralCheckType
5921llvm::SmallBitVector &CheckedVarArgs,
5922UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5923 boolIgnoreStringsWithoutSpecifiers =
false) {
5925 returnSLCT_NotALiteral;
5927assert(Offset.isSigned() &&
"invalid offset");
5930 returnSLCT_NotALiteral;
5939 returnSLCT_UncheckedLiteral;
5942 caseStmt::InitListExprClass:
5946 Type, CallType,
false,
5947CheckedVarArgs, UncoveredArg, Offset,
5948IgnoreStringsWithoutSpecifiers);
5950 returnSLCT_NotALiteral;
5951 caseStmt::BinaryConditionalOperatorClass:
5952 caseStmt::ConditionalOperatorClass: {
5956cast<AbstractConditionalOperator>(
E);
5961 boolCheckLeft =
true, CheckRight =
true;
5964 if(
C->getCond()->EvaluateAsBooleanCondition(
5967CheckRight =
false;
5976StringLiteralCheckType Left;
5978Left = SLCT_UncheckedLiteral;
5981firstDataArg,
Type, CallType, InFunctionCall,
5982CheckedVarArgs, UncoveredArg, Offset,
5983IgnoreStringsWithoutSpecifiers);
5984 if(Left == SLCT_NotALiteral || !CheckRight) {
5990S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5991CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5992IgnoreStringsWithoutSpecifiers);
5994 return(CheckLeft && Left < Right) ? Left : Right;
5997 caseStmt::ImplicitCastExprClass:
5998 E= cast<ImplicitCastExpr>(
E)->getSubExpr();
6001 caseStmt::OpaqueValueExprClass:
6002 if(
const Expr*src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
6006 returnSLCT_NotALiteral;
6008 caseStmt::PredefinedExprClass:
6012 returnSLCT_UncheckedLiteral;
6014 caseStmt::DeclRefExprClass: {
6020 boolisConstant =
false;
6024isConstant = AT->getElementType().isConstant(S.
Context);
6026isConstant =
T.isConstant(S.
Context) &&
6031isConstant =
T.isConstant(S.
Context);
6035 if(
const Expr*
Init= VD->getAnyInitializer()) {
6038 if(InitList->isStringLiteralInit())
6039 Init= InitList->getInit(0)->IgnoreParenImpCasts();
6042S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
6043 false, CheckedVarArgs, UncoveredArg, Offset);
6084 if(
const auto*PV = dyn_cast<ParmVarDecl>(VD)) {
6085 if(
const auto*
D= dyn_cast<Decl>(PV->getDeclContext())) {
6087 boolIsCXXMember =
false;
6088 if(
const auto*MD = dyn_cast<CXXMethodDecl>(
D))
6089IsCXXMember = MD->isInstance();
6091 boolIsVariadic =
false;
6093IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
6094 else if(
const auto*BD = dyn_cast<BlockDecl>(
D))
6095IsVariadic = BD->isVariadic();
6096 else if(
const auto*OMD = dyn_cast<ObjCMethodDecl>(
D))
6097IsVariadic = OMD->isVariadic();
6104 if(PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx&&
6117 returnSLCT_UncheckedLiteral;
6126 returnSLCT_NotALiteral;
6129 caseStmt::CallExprClass:
6130 caseStmt::CXXMemberCallExprClass: {
6131 const CallExpr*CE = cast<CallExpr>(
E);
6133 boolIsFirst =
true;
6134StringLiteralCheckType CommonResult;
6135 for(
const auto*FA : ND->specific_attrs<FormatArgAttr>()) {
6136 const Expr*Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6138S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6139InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6140IgnoreStringsWithoutSpecifiers);
6147 returnCommonResult;
6149 if(
const auto*FD = dyn_cast<FunctionDecl>(ND)) {
6151 if(BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6152BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6155S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6156InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6157IgnoreStringsWithoutSpecifiers);
6163 Type, CallType,
false,
6164CheckedVarArgs, UncoveredArg, Offset,
6165IgnoreStringsWithoutSpecifiers);
6166 returnSLCT_NotALiteral;
6168 caseStmt::ObjCMessageExprClass: {
6169 const auto*ME = cast<ObjCMessageExpr>(
E);
6170 if(
const auto*MD = ME->getMethodDecl()) {
6171 if(
const auto*FA = MD->getAttr<FormatArgAttr>()) {
6180 if(MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6182MD->getSelector().isKeywordSelector(
6183{
"localizedStringForKey",
"value",
"table"})) {
6184IgnoreStringsWithoutSpecifiers =
true;
6187 const Expr*Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6189S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6190InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6191IgnoreStringsWithoutSpecifiers);
6195 returnSLCT_NotALiteral;
6197 caseStmt::ObjCStringLiteralClass:
6198 caseStmt::StringLiteralClass: {
6204StrE = cast<StringLiteral>(
E);
6207 if(Offset.isNegative() || Offset > StrE->
getLength()) {
6210 returnSLCT_NotALiteral;
6212FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6214InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
6215IgnoreStringsWithoutSpecifiers);
6216 returnSLCT_CheckedLiteral;
6219 returnSLCT_NotALiteral;
6221 caseStmt::BinaryOperatorClass: {
6235 if(LIsInt != RIsInt) {
6239 if(BinOpKind == BO_Add) {
6252 returnSLCT_NotALiteral;
6254 caseStmt::UnaryOperatorClass: {
6256 autoASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6257 if(UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6259 if(ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6269 returnSLCT_NotALiteral;
6273 returnSLCT_NotALiteral;
6284 const auto*LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr*>();
6285 if(isa_and_nonnull<StringLiteral>(LVE))
6292 returnllvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6294.Cases(
"printf",
"printf0",
"syslog",
FST_Printf)
6298.Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6305boolSema::CheckFormatArguments(
constFormatAttr *Format,
6309llvm::SmallBitVector &CheckedVarArgs) {
6310FormatStringInfo FSI;
6313 returnCheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6315CallType,
Loc,
Range, CheckedVarArgs);
6321 unsignedformat_idx,
unsignedfirstDataArg,
6322FormatStringType
Type,
6325llvm::SmallBitVector &CheckedVarArgs) {
6327 if(format_idx >= Args.size()) {
6328 Diag(
Loc, diag::warn_missing_format_string) <<
Range;
6332 const Expr*OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6346UncoveredArgHandler UncoveredArg;
6348*
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6350 true, CheckedVarArgs, UncoveredArg,
6351llvm::APSInt(64,
false) = 0);
6354 if(UncoveredArg.hasUncoveredArg()) {
6355 unsignedArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6356assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6357UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6360 if(CT != SLCT_NotALiteral)
6362 returnCT == SLCT_CheckedLiteral;
6379 if(Args.size() == firstDataArg) {
6380 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6389 Diag(FormatLoc, diag::note_format_security_fixit)
6393 Diag(FormatLoc, diag::note_format_security_fixit)
6398 Diag(FormatLoc, diag::warn_format_nonliteral)
6409 constFormatStringLiteral *FExpr;
6410 const Expr*OrigFormatExpr;
6412 const unsignedFirstDataArg;
6413 const unsignedNumDataArgs;
6418llvm::SmallBitVector CoveredArgs;
6419 boolusesPositionalArgs =
false;
6420 boolatFirstArg =
true;
6421 boolinFunctionCall;
6423llvm::SmallBitVector &CheckedVarArgs;
6424UncoveredArgHandler &UncoveredArg;
6427CheckFormatHandler(
Sema&
s,
constFormatStringLiteral *fexpr,
6428 const Expr*origFormatExpr,
6430 unsignednumDataArgs,
const char*beg,
6434llvm::SmallBitVector &CheckedVarArgs,
6435UncoveredArgHandler &UncoveredArg)
6436: S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6437FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6438ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6439inFunctionCall(inFunctionCall), CallType(callType),
6440CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6441CoveredArgs.resize(numDataArgs);
6442CoveredArgs.reset();
6445 voidDoneProcessing();
6447 voidHandleIncompleteSpecifier(
const char*startSpecifier,
6448 unsignedspecifierLen)
override;
6450 voidHandleInvalidLengthModifier(
6453 const char*startSpecifier,
unsignedspecifierLen,
6456 voidHandleNonStandardLengthModifier(
6458 const char*startSpecifier,
unsignedspecifierLen);
6460 voidHandleNonStandardConversionSpecifier(
6462 const char*startSpecifier,
unsignedspecifierLen);
6464 voidHandlePosition(
const char*startPos,
unsignedposLen)
override;
6466 voidHandleInvalidPosition(
const char*startSpecifier,
6467 unsignedspecifierLen,
6470 voidHandleZeroPosition(
const char*startPos,
unsignedposLen)
override;
6472 voidHandleNullChar(
const char*nullCharacter)
override;
6474 template<
typenameRange>
6476EmitFormatDiagnostic(
Sema&S,
boolinFunctionCall,
const Expr*ArgumentExpr,
6478 boolIsStringLocation,
RangeStringRange,
6483 const char*startSpec,
6484 unsignedspecifierLen,
6485 const char*csStart,
unsignedcsLen);
6488 const char*startSpec,
6489 unsignedspecifierLen);
6493 unsignedspecifierLen);
6496 const Expr*getDataArg(
unsignedi)
const;
6500 const char*startSpecifier,
unsignedspecifierLen,
6503 template<
typenameRange>
6505 boolIsStringLocation,
RangeStringRange,
6511SourceRangeCheckFormatHandler::getFormatStringRange() {
6516getSpecifierRange(
const char*startSpecifier,
unsignedspecifierLen) {
6518 SourceLocationEnd = getLocationOfByte(startSpecifier + specifierLen - 1);
6521End = End.getLocWithOffset(1);
6526SourceLocationCheckFormatHandler::getLocationOfByte(
const char*x) {
6531voidCheckFormatHandler::HandleIncompleteSpecifier(
const char*startSpecifier,
6532 unsignedspecifierLen){
6533EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6534getLocationOfByte(startSpecifier),
6536getSpecifierRange(startSpecifier, specifierLen));
6539voidCheckFormatHandler::HandleInvalidLengthModifier(
6542 const char*startSpecifier,
unsignedspecifierLen,
unsignedDiagID) {
6543 using namespaceanalyze_format_string;
6545 constLengthModifier &LM = FS.getLengthModifier();
6546 CharSourceRangeLMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6549std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6551EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6552getLocationOfByte(LM.getStart()),
6554getSpecifierRange(startSpecifier, specifierLen));
6556S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6557<< FixedLM->toString()
6562 if(DiagID == diag::warn_format_nonsensical_length)
6565EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6566getLocationOfByte(LM.getStart()),
6568getSpecifierRange(startSpecifier, specifierLen),
6573voidCheckFormatHandler::HandleNonStandardLengthModifier(
6575 const char*startSpecifier,
unsignedspecifierLen) {
6576 using namespaceanalyze_format_string;
6578 constLengthModifier &LM = FS.getLengthModifier();
6579 CharSourceRangeLMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6582std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6584EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6585<< LM.toString() << 0,
6586getLocationOfByte(LM.getStart()),
6588getSpecifierRange(startSpecifier, specifierLen));
6590S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6591<< FixedLM->toString()
6595EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6596<< LM.toString() << 0,
6597getLocationOfByte(LM.getStart()),
6599getSpecifierRange(startSpecifier, specifierLen));
6603voidCheckFormatHandler::HandleNonStandardConversionSpecifier(
6605 const char*startSpecifier,
unsignedspecifierLen) {
6606 using namespaceanalyze_format_string;
6611EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6613getLocationOfByte(CS.
getStart()),
6615getSpecifierRange(startSpecifier, specifierLen));
6618S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6619<< FixedCS->toString()
6622EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6624getLocationOfByte(CS.
getStart()),
6626getSpecifierRange(startSpecifier, specifierLen));
6630voidCheckFormatHandler::HandlePosition(
const char*startPos,
6633diag::warn_format_non_standard_positional_arg,
SourceLocation()))
6634EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6635getLocationOfByte(startPos),
6637getSpecifierRange(startPos, posLen));
6640voidCheckFormatHandler::HandleInvalidPosition(
6641 const char*startSpecifier,
unsignedspecifierLen,
6644diag::warn_format_invalid_positional_specifier,
SourceLocation()))
6645EmitFormatDiagnostic(
6646S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6647getLocationOfByte(startSpecifier),
true,
6648getSpecifierRange(startSpecifier, specifierLen));
6651voidCheckFormatHandler::HandleZeroPosition(
const char*startPos,
6655EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6656getLocationOfByte(startPos),
6658getSpecifierRange(startPos, posLen));
6661voidCheckFormatHandler::HandleNullChar(
const char*nullCharacter) {
6662 if(!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6664EmitFormatDiagnostic(
6665S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6666getLocationOfByte(nullCharacter),
true,
6667getFormatStringRange());
6673const Expr*CheckFormatHandler::getDataArg(
unsignedi)
const{
6674 returnArgs[FirstDataArg + i];
6677voidCheckFormatHandler::DoneProcessing() {
6683 signednotCoveredArg = CoveredArgs.find_first();
6684 if(notCoveredArg >= 0) {
6685assert((
unsigned)notCoveredArg < NumDataArgs);
6686UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6688UncoveredArg.setAllCovered();
6693voidUncoveredArgHandler::Diagnose(
Sema&S,
boolIsFunctionCall,
6694 const Expr*ArgExpr) {
6695assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6707 for(
auto E: DiagnosticExprs)
6710CheckFormatHandler::EmitFormatDiagnostic(
6711S, IsFunctionCall, DiagnosticExprs[0],
6712PDiag,
Loc,
false,
6717CheckFormatHandler::HandleInvalidConversionSpecifier(
unsignedargIndex,
6719 const char*startSpec,
6720 unsignedspecifierLen,
6721 const char*csStart,
6723 boolkeepGoing =
true;
6724 if(argIndex < NumDataArgs) {
6727CoveredArgs.set(argIndex);
6743std::string CodePointStr;
6744 if(!llvm::sys::locale::isPrint(*csStart)) {
6745llvm::UTF32 CodePoint;
6746 constllvm::UTF8 **B =
reinterpret_cast<constllvm::UTF8 **
>(&csStart);
6747 constllvm::UTF8 *
E=
6748 reinterpret_cast<constllvm::UTF8 *
>(csStart + csLen);
6749llvm::ConversionResult
Result=
6750llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6752 if(
Result!= llvm::conversionOK) {
6753 unsigned charFirstChar = *csStart;
6754CodePoint = (llvm::UTF32)FirstChar;
6757llvm::raw_string_ostream OS(CodePointStr);
6758 if(CodePoint < 256)
6759OS <<
"\\x"<< llvm::format(
"%02x", CodePoint);
6760 else if(CodePoint <= 0xFFFF)
6761OS <<
"\\u"<< llvm::format(
"%04x", CodePoint);
6763OS <<
"\\U"<< llvm::format(
"%08x", CodePoint);
6767EmitFormatDiagnostic(
6768S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6769 true, getSpecifierRange(startSpec, specifierLen));
6776 const char*startSpec,
6777 unsignedspecifierLen) {
6778EmitFormatDiagnostic(
6779S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6780 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6784CheckFormatHandler::CheckNumArgs(
6787 const char*startSpecifier,
unsignedspecifierLen,
unsignedargIndex) {
6789 if(argIndex >= NumDataArgs) {
6791? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6792<< (argIndex+1) << NumDataArgs)
6793: S.
PDiag(diag::warn_printf_insufficient_data_args);
6794EmitFormatDiagnostic(
6795PDiag, getLocationOfByte(CS.
getStart()),
true,
6796getSpecifierRange(startSpecifier, specifierLen));
6800UncoveredArg.setAllCovered();
6806template<
typenameRange>
6809 boolIsStringLocation,
6812EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6813 Loc, IsStringLocation, StringRange, FixIt);
6843template<
typenameRange>
6844voidCheckFormatHandler::EmitFormatDiagnostic(
6845 Sema&S,
boolInFunctionCall,
const Expr*ArgumentExpr,
6848 if(InFunctionCall) {
6857S.
Diag(IsStringLocation ?
Loc: StringRange.getBegin(),
6858diag::note_format_string_defined);
6860 Note<< StringRange;
6869classCheckPrintfHandler :
publicCheckFormatHandler {
6871CheckPrintfHandler(
Sema&
s,
constFormatStringLiteral *fexpr,
6872 const Expr*origFormatExpr,
6874 unsignednumDataArgs,
boolisObjC,
const char*beg,
6878llvm::SmallBitVector &CheckedVarArgs,
6879UncoveredArgHandler &UncoveredArg)
6880: CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6881numDataArgs, beg, APK, Args, formatIdx,
6882inFunctionCall, CallType, CheckedVarArgs,
6888 boolallowsObjCArg()
const{
6893 boolHandleInvalidPrintfConversionSpecifier(
6895 const char*startSpecifier,
6896 unsignedspecifierLen)
override;
6898 voidhandleInvalidMaskType(StringRef MaskType)
override;
6901 const char*startSpecifier,
unsignedspecifierLen,
6904 const char*StartSpecifier,
6905 unsignedSpecifierLen,
6909 const char*startSpecifier,
unsignedspecifierLen);
6913 const char*startSpecifier,
unsignedspecifierLen);
6916 const char*startSpecifier,
unsignedspecifierLen);
6920 const char*startSpecifier,
unsignedspecifierLen);
6924 voidHandleEmptyObjCModifierFlag(
const char*startFlag,
6925 unsignedflagLen)
override;
6927 voidHandleInvalidObjCModifierFlag(
const char*startFlag,
6928 unsignedflagLen)
override;
6930 voidHandleObjCFlagsWithNonObjCConversion(
const char*flagsStart,
6931 const char*flagsEnd,
6932 const char*conversionPosition)
6938boolCheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6940 const char*startSpecifier,
6941 unsignedspecifierLen) {
6943FS.getConversionSpecifier();
6945 returnHandleInvalidConversionSpecifier(FS.getArgIndex(),
6946getLocationOfByte(CS.
getStart()),
6947startSpecifier, specifierLen,
6951voidCheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6952S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6955boolCheckPrintfHandler::HandleAmount(
6957 const char*startSpecifier,
unsignedspecifierLen) {
6961 if(argIndex >= NumDataArgs) {
6962EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6964getLocationOfByte(Amt.
getStart()),
6966getSpecifierRange(startSpecifier, specifierLen));
6976CoveredArgs.set(argIndex);
6977 const Expr*Arg = getDataArg(argIndex);
6987EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6990getLocationOfByte(Amt.
getStart()),
6992getSpecifierRange(startSpecifier, specifierLen));
7002voidCheckPrintfHandler::HandleInvalidAmount(
7006 const char*startSpecifier,
7007 unsignedspecifierLen) {
7009FS.getConversionSpecifier();
7017EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7019getLocationOfByte(Amt.
getStart()),
7021getSpecifierRange(startSpecifier, specifierLen),
7027 const char*startSpecifier,
7028 unsignedspecifierLen) {
7031FS.getConversionSpecifier();
7032EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7036getSpecifierRange(startSpecifier, specifierLen),
7041voidCheckPrintfHandler::HandleIgnoredFlag(
7045 const char*startSpecifier,
7046 unsignedspecifierLen) {
7048EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7052getSpecifierRange(startSpecifier, specifierLen),
7054getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7057voidCheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char*startFlag,
7060EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7061getLocationOfByte(startFlag),
7063getSpecifierRange(startFlag, flagLen));
7066voidCheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char*startFlag,
7069 auto Range= getSpecifierRange(startFlag, flagLen);
7070StringRef flag(startFlag, flagLen);
7071EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7072getLocationOfByte(startFlag),
7077voidCheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7078 const char*flagsStart,
const char*flagsEnd,
const char*conversionPosition) {
7080 auto Range= getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7081 autodiag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7082EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7083getLocationOfByte(conversionPosition),
7091template<
typenameMemberKind>
7112 if(MemberKind *FK = dyn_cast<MemberKind>(
decl))
7126CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7127 for(MethodSet::iterator MI = Results.begin(), ME = Results.end();
7129 if((*MI)->getMinRequiredArguments() == 0)
7137boolCheckPrintfHandler::checkForCStrMembers(
7142CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7144 for(MethodSet::iterator MI = Results.begin(), ME = Results.end();
7160boolCheckPrintfHandler::HandlePrintfSpecifier(
7163 using namespaceanalyze_format_string;
7164 using namespaceanalyze_printf;
7166 constPrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7168 if(FS.consumesDataArgument()) {
7170atFirstArg =
false;
7171usesPositionalArgs = FS.usesPositionalArg();
7173 else if(usesPositionalArgs != FS.usesPositionalArg()) {
7174HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7175startSpecifier, specifierLen);
7182 if(!HandleAmount(FS.getFieldWidth(),
0,
7183startSpecifier, specifierLen)) {
7187 if(!HandleAmount(FS.getPrecision(),
1,
7188startSpecifier, specifierLen)) {
7192 if(!CS.consumesDataArgument()) {
7199 unsignedargIndex = FS.getArgIndex();
7200 if(argIndex < NumDataArgs) {
7204CoveredArgs.set(argIndex);
7208 if(CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
7209CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
7211 if(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
7215CoveredArgs.set(argIndex + 1);
7218 const Expr*Ex = getDataArg(argIndex);
7220(CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
7223EmitFormatDiagnostic(
7224S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7228getSpecifierRange(startSpecifier, specifierLen));
7231Ex = getDataArg(argIndex + 1);
7234EmitFormatDiagnostic(
7235S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7239getSpecifierRange(startSpecifier, specifierLen));
7246 if(!allowsObjCArg() && CS.isObjCArg()) {
7247 returnHandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7252 if(FSType !=
Sema::FST_OSLog&& CS.getKind() == ConversionSpecifier::PArg) {
7253 returnHandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7258 if(FSType ==
Sema::FST_OSLog&& CS.getKind() == ConversionSpecifier::nArg) {
7259EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7260getLocationOfByte(CS.getStart()),
7262getSpecifierRange(startSpecifier, specifierLen));
7269(CS.getKind() == ConversionSpecifier::PArg ||
7270CS.getKind() == ConversionSpecifier::sArg ||
7271CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7272 returnHandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7278 if(FS.isPublic().isSet()) {
7279EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7281getLocationOfByte(FS.isPublic().getPosition()),
7283getSpecifierRange(startSpecifier, specifierLen));
7285 if(FS.isPrivate().isSet()) {
7286EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7288getLocationOfByte(FS.isPrivate().getPosition()),
7290getSpecifierRange(startSpecifier, specifierLen));
7294 constllvm::Triple &Triple =
Target.getTriple();
7295 if(CS.getKind() == ConversionSpecifier::nArg &&
7296(Triple.isAndroid() || Triple.isOSFuchsia())) {
7297EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7298getLocationOfByte(CS.getStart()),
7300getSpecifierRange(startSpecifier, specifierLen));
7304 if(!FS.hasValidFieldWidth()) {
7305HandleInvalidAmount(FS, FS.getFieldWidth(),
0,
7306startSpecifier, specifierLen);
7310 if(!FS.hasValidPrecision()) {
7311HandleInvalidAmount(FS, FS.getPrecision(),
1,
7312startSpecifier, specifierLen);
7316 if(CS.getKind() == ConversionSpecifier::PArg &&
7317FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7318EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7319getLocationOfByte(startSpecifier),
7321getSpecifierRange(startSpecifier, specifierLen));
7325 if(!FS.hasValidThousandsGroupingPrefix())
7326HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7327 if(!FS.hasValidLeadingZeros())
7328HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7329 if(!FS.hasValidPlusPrefix())
7330HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7331 if(!FS.hasValidSpacePrefix())
7332HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7333 if(!FS.hasValidAlternativeForm())
7334HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7335 if(!FS.hasValidLeftJustified())
7336HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7339 if(FS.hasSpacePrefix() && FS.hasPlusPrefix())
7340HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7341startSpecifier, specifierLen);
7342 if(FS.hasLeadingZeros() && FS.isLeftJustified())
7343HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7344startSpecifier, specifierLen);
7349HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7350diag::warn_format_nonsensical_length);
7351 else if(!FS.hasStandardLengthModifier())
7352HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7353 else if(!FS.hasStandardLengthConversionCombination())
7354HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7355diag::warn_format_non_standard_conversion_spec);
7357 if(!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7358HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7364 if(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7367 const Expr*Arg = getDataArg(argIndex);
7371 returncheckFormatExpr(FS, startSpecifier, specifierLen, Arg);
7383 caseStmt::ArraySubscriptExprClass:
7384 caseStmt::CallExprClass:
7385 caseStmt::CharacterLiteralClass:
7386 caseStmt::CXXBoolLiteralExprClass:
7387 caseStmt::DeclRefExprClass:
7388 caseStmt::FloatingLiteralClass:
7389 caseStmt::IntegerLiteralClass:
7390 caseStmt::MemberExprClass:
7391 caseStmt::ObjCArrayLiteralClass:
7392 caseStmt::ObjCBoolLiteralExprClass:
7393 caseStmt::ObjCBoxedExprClass:
7394 caseStmt::ObjCDictionaryLiteralClass:
7395 caseStmt::ObjCEncodeExprClass:
7396 caseStmt::ObjCIvarRefExprClass:
7397 caseStmt::ObjCMessageExprClass:
7398 caseStmt::ObjCPropertyRefExprClass:
7399 caseStmt::ObjCStringLiteralClass:
7400 caseStmt::ObjCSubscriptRefExprClass:
7401 caseStmt::ParenExprClass:
7402 caseStmt::StringLiteralClass:
7403 caseStmt::UnaryOperatorClass:
7410staticstd::pair<QualType, StringRef>
7417StringRef Name = UserTy->getDecl()->getName();
7418 QualTypeCastTy = llvm::StringSwitch<QualType>(Name)
7422.Case(
"SInt32", Context.
IntTy)
7427 returnstd::make_pair(CastTy, Name);
7429TyTy = UserTy->desugar();
7433 if(
const ParenExpr*PE = dyn_cast<ParenExpr>(
E))
7435PE->getSubExpr()->getType(),
7444StringRef TrueName, FalseName;
7446std::tie(TrueTy, TrueName) =
7448CO->getTrueExpr()->getType(),
7450std::tie(FalseTy, FalseName) =
7452CO->getFalseExpr()->getType(),
7453CO->getFalseExpr());
7455 if(TrueTy == FalseTy)
7456 returnstd::make_pair(TrueTy, TrueName);
7457 else if(TrueTy.
isNull())
7458 returnstd::make_pair(FalseTy, FalseName);
7459 else if(FalseTy.
isNull())
7460 returnstd::make_pair(TrueTy, TrueName);
7463 returnstd::make_pair(
QualType(), StringRef());
7482From = VecTy->getElementType();
7484To = VecTy->getElementType();
7496diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7505 const char*StartSpecifier,
7506 unsignedSpecifierLen,
7508 using namespaceanalyze_format_string;
7509 using namespaceanalyze_printf;
7518 while(
const TypeOfExprType*TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7519ExprTy = TET->getUnderlyingExpr()->getType();
7531 if(FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7534getSpecifierRange(StartSpecifier, SpecifierLen);
7536llvm::raw_svector_ostream os(FSString);
7538EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7546 if(FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7549getSpecifierRange(StartSpecifier, SpecifierLen);
7550EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7555ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7557ArgType::MatchKind OrigMatch = Match;
7560 if(Match == ArgType::Match)
7564assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7573 E= ICE->getSubExpr();
7583 if(OrigMatch == ArgType::NoMatchSignedness &&
7584ImplicitMatch != ArgType::NoMatchSignedness)
7591 if(ImplicitMatch == ArgType::Match)
7602FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7609 if(Match == ArgType::MatchPromotion)
7610Match = ArgType::NoMatch;
7613 if(Match == ArgType::MatchPromotion) {
7617ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7618ImplicitMatch != ArgType::NoMatchTypeConfusion)
7620Match = ArgType::NoMatch;
7622 if(ImplicitMatch == ArgType::NoMatchPedantic ||
7623ImplicitMatch == ArgType::NoMatchTypeConfusion)
7624Match = ImplicitMatch;
7625assert(Match != ArgType::MatchPromotion);
7628 boolIsEnum =
false;
7629 boolIsScopedEnum =
false;
7632IntendedTy = EnumTy->getDecl()->getIntegerType();
7633 if(EnumTy->isUnscopedEnumerationType()) {
7634ExprTy = IntendedTy;
7639IsScopedEnum =
true;
7646 if(isObjCContext() &&
7647FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7657 constllvm::APInt &
V= IL->getValue();
7667 if(TD->getUnderlyingType() == IntendedTy)
7675 boolShouldNotPrintDirectly =
false; StringRef CastTyName;
7679 if(!CastTy.
isNull()) {
7683 if(!IsScopedEnum &&
7684(CastTyName ==
"NSInteger"|| CastTyName ==
"NSUInteger") &&
7687Match = ArgType::NoMatchPedantic;
7688IntendedTy = CastTy;
7689ShouldNotPrintDirectly =
true;
7694PrintfSpecifier fixedFS = FS;
7701llvm::raw_svector_ostream os(buf);
7702fixedFS.toString(os);
7704 CharSourceRangeSpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7706 if(IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7709 caseArgType::Match:
7710 caseArgType::MatchPromotion:
7711 caseArgType::NoMatchPromotionTypeConfusion:
7712 caseArgType::NoMatchSignedness:
7713llvm_unreachable(
"expected non-matching");
7714 caseArgType::NoMatchPedantic:
7715 Diag= diag::warn_format_conversion_argument_type_mismatch_pedantic;
7717 caseArgType::NoMatchTypeConfusion:
7718 Diag= diag::warn_format_conversion_argument_type_mismatch_confusion;
7720 caseArgType::NoMatch:
7721 Diag= diag::warn_format_conversion_argument_type_mismatch;
7742llvm::raw_svector_ostream CastFix(CastBuf);
7743CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<":
"(");
7745CastFix << (S.
LangOpts.CPlusPlus ?
">":
")");
7751 if((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7756 SourceRangeCastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7778 if(ShouldNotPrintDirectly && !IsScopedEnum) {
7784Name = TypedefTy->getDecl()->getName();
7787 unsigned Diag= Match == ArgType::NoMatchPedantic
7788? diag::warn_format_argument_needs_cast_pedantic
7789: diag::warn_format_argument_needs_cast;
7790EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7801? diag::warn_format_conversion_argument_type_mismatch_pedantic
7802: diag::warn_format_conversion_argument_type_mismatch;
7804EmitFormatDiagnostic(
7816 boolEmitTypeMismatch =
false;
7822 caseArgType::Match:
7823 caseArgType::MatchPromotion:
7824 caseArgType::NoMatchPromotionTypeConfusion:
7825 caseArgType::NoMatchSignedness:
7826llvm_unreachable(
"expected non-matching");
7827 caseArgType::NoMatchPedantic:
7828 Diag= diag::warn_format_conversion_argument_type_mismatch_pedantic;
7830 caseArgType::NoMatchTypeConfusion:
7831 Diag= diag::warn_format_conversion_argument_type_mismatch_confusion;
7833 caseArgType::NoMatch:
7834 Diag= diag::warn_format_conversion_argument_type_mismatch;
7838EmitFormatDiagnostic(
7847EmitTypeMismatch =
true;
7849EmitFormatDiagnostic(
7850S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7851<< S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7855checkForCStrMembers(AT,
E);
7861EmitTypeMismatch =
true;
7863EmitFormatDiagnostic(
7864S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7865<< S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7873<< isa<InitListExpr>(
E) << ExprTy << CallType
7878 if(EmitTypeMismatch) {
7884EmitFormatDiagnostic(
7885S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7891assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7892 "format string specifier index out of range");
7893CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7903classCheckScanfHandler :
publicCheckFormatHandler {
7905CheckScanfHandler(
Sema&
s,
constFormatStringLiteral *fexpr,
7907 unsignedfirstDataArg,
unsignednumDataArgs,
7911llvm::SmallBitVector &CheckedVarArgs,
7912UncoveredArgHandler &UncoveredArg)
7913: CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7914numDataArgs, beg, APK, Args, formatIdx,
7915inFunctionCall, CallType, CheckedVarArgs,
7919 const char*startSpecifier,
7920 unsignedspecifierLen)
override;
7922 boolHandleInvalidScanfConversionSpecifier(
7924 const char*startSpecifier,
7925 unsignedspecifierLen)
override;
7927 voidHandleIncompleteScanList(
const char*start,
const char*end)
override;
7932voidCheckScanfHandler::HandleIncompleteScanList(
const char*start,
7934EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7935getLocationOfByte(end),
true,
7936getSpecifierRange(start, end - start));
7939boolCheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7941 const char*startSpecifier,
7942 unsignedspecifierLen) {
7944FS.getConversionSpecifier();
7946 returnHandleInvalidConversionSpecifier(FS.getArgIndex(),
7947getLocationOfByte(CS.
getStart()),
7948startSpecifier, specifierLen,
7952boolCheckScanfHandler::HandleScanfSpecifier(
7954 const char*startSpecifier,
7955 unsignedspecifierLen) {
7956 using namespaceanalyze_scanf;
7957 using namespaceanalyze_format_string;
7959 constScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7963 if(FS.consumesDataArgument()) {
7965atFirstArg =
false;
7966usesPositionalArgs = FS.usesPositionalArg();
7968 else if(usesPositionalArgs != FS.usesPositionalArg()) {
7969HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7970startSpecifier, specifierLen);
7976 constOptionalAmount &Amt = FS.getFieldWidth();
7977 if(Amt.getHowSpecified() == OptionalAmount::Constant) {
7978 if(Amt.getConstantAmount() == 0) {
7980Amt.getConstantLength());
7981EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7982getLocationOfByte(Amt.getStart()),
7988 if(!FS.consumesDataArgument()) {
7995 unsignedargIndex = FS.getArgIndex();
7996 if(argIndex < NumDataArgs) {
8000CoveredArgs.set(argIndex);
8006HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8007diag::warn_format_nonsensical_length);
8008 else if(!FS.hasStandardLengthModifier())
8009HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8010 else if(!FS.hasStandardLengthConversionCombination())
8011HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8012diag::warn_format_non_standard_conversion_spec);
8014 if(!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8015HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8021 if(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8025 const Expr*Ex = getDataArg(argIndex);
8042ScanfSpecifier fixedFS = FS;
8047 Pedantic? diag::warn_format_conversion_argument_type_mismatch_pedantic
8048: diag::warn_format_conversion_argument_type_mismatch;
8053llvm::raw_svector_ostream os(buf);
8054fixedFS.toString(os);
8056EmitFormatDiagnostic(
8061getSpecifierRange(startSpecifier, specifierLen),
8063getSpecifierRange(startSpecifier, specifierLen), os.str()));
8070getSpecifierRange(startSpecifier, specifierLen));
8077 Sema&S,
constFormatStringLiteral *FExpr,
const Expr*OrigFormatExpr,
8081llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8082 boolIgnoreStringsWithoutSpecifiers) {
8084 if(!FExpr->isAscii() && !FExpr->isUTF8()) {
8085CheckFormatHandler::EmitFormatDiagnostic(
8086S, inFunctionCall, Args[format_idx],
8087S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8093StringRef StrRef = FExpr->getString();
8094 const char*Str = StrRef.data();
8098assert(
T&&
"String literal not of constant array type!");
8099 size_tTypeSize =
T->getZExtSize();
8100 size_tStrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8101 const unsignednumDataArgs = Args.size() - firstDataArg;
8103 if(IgnoreStringsWithoutSpecifiers &&
8110 if(TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8111CheckFormatHandler::EmitFormatDiagnostic(
8112S, inFunctionCall, Args[format_idx],
8113S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8114FExpr->getBeginLoc(),
8120 if(StrLen == 0 && numDataArgs > 0) {
8121CheckFormatHandler::EmitFormatDiagnostic(
8122S, inFunctionCall, Args[format_idx],
8123S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
8132CheckPrintfHandler H(
8133S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
8135Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
8143CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
8144numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
8145CallType, CheckedVarArgs, UncoveredArg);
8155StringRef StrRef = FExpr->
getString();
8156 const char*Str = StrRef.data();
8159assert(
T&&
"String literal not of constant array type!");
8160 size_tTypeSize =
T->getZExtSize();
8161 size_tStrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8172 switch(AbsFunction) {
8176 caseBuiltin::BI__builtin_abs:
8177 returnBuiltin::BI__builtin_labs;
8178 caseBuiltin::BI__builtin_labs:
8179 returnBuiltin::BI__builtin_llabs;
8180 caseBuiltin::BI__builtin_llabs:
8183 caseBuiltin::BI__builtin_fabsf:
8184 returnBuiltin::BI__builtin_fabs;
8185 caseBuiltin::BI__builtin_fabs:
8186 returnBuiltin::BI__builtin_fabsl;
8187 caseBuiltin::BI__builtin_fabsl:
8190 caseBuiltin::BI__builtin_cabsf:
8191 returnBuiltin::BI__builtin_cabs;
8192 caseBuiltin::BI__builtin_cabs:
8193 returnBuiltin::BI__builtin_cabsl;
8194 caseBuiltin::BI__builtin_cabsl:
8197 caseBuiltin::BIabs:
8198 returnBuiltin::BIlabs;
8199 caseBuiltin::BIlabs:
8200 returnBuiltin::BIllabs;
8201 caseBuiltin::BIllabs:
8204 caseBuiltin::BIfabsf:
8205 returnBuiltin::BIfabs;
8206 caseBuiltin::BIfabs:
8207 returnBuiltin::BIfabsl;
8208 caseBuiltin::BIfabsl:
8211 caseBuiltin::BIcabsf:
8212 returnBuiltin::BIcabs;
8213 caseBuiltin::BIcabs:
8214 returnBuiltin::BIcabsl;
8215 caseBuiltin::BIcabsl:
8244 unsignedAbsFunctionKind) {
8245 unsignedBestKind = 0;
8246uint64_t ArgSize = Context.
getTypeSize(ArgType);
8247 for(
unsignedKind = AbsFunctionKind; Kind != 0;
8250 if(Context.
getTypeSize(ParamType) >= ArgSize) {
8253 else if(Context.
hasSameType(ParamType, ArgType)) {
8276llvm_unreachable(
"Type not integer, floating, or complex");
8283 switch(ValueKind) {
8288 caseBuiltin::BI__builtin_fabsf:
8289 caseBuiltin::BI__builtin_fabs:
8290 caseBuiltin::BI__builtin_fabsl:
8291 caseBuiltin::BI__builtin_cabsf:
8292 caseBuiltin::BI__builtin_cabs:
8293 caseBuiltin::BI__builtin_cabsl:
8294 returnBuiltin::BI__builtin_abs;
8295 caseBuiltin::BIfabsf:
8296 caseBuiltin::BIfabs:
8297 caseBuiltin::BIfabsl:
8298 caseBuiltin::BIcabsf:
8299 caseBuiltin::BIcabs:
8300 caseBuiltin::BIcabsl:
8301 returnBuiltin::BIabs;
8307 caseBuiltin::BI__builtin_abs:
8308 caseBuiltin::BI__builtin_labs:
8309 caseBuiltin::BI__builtin_llabs:
8310 caseBuiltin::BI__builtin_cabsf:
8311 caseBuiltin::BI__builtin_cabs:
8312 caseBuiltin::BI__builtin_cabsl:
8313 returnBuiltin::BI__builtin_fabsf;
8314 caseBuiltin::BIabs:
8315 caseBuiltin::BIlabs:
8316 caseBuiltin::BIllabs:
8317 caseBuiltin::BIcabsf:
8318 caseBuiltin::BIcabs:
8319 caseBuiltin::BIcabsl:
8320 returnBuiltin::BIfabsf;
8326 caseBuiltin::BI__builtin_abs:
8327 caseBuiltin::BI__builtin_labs:
8328 caseBuiltin::BI__builtin_llabs:
8329 caseBuiltin::BI__builtin_fabsf:
8330 caseBuiltin::BI__builtin_fabs:
8331 caseBuiltin::BI__builtin_fabsl:
8332 returnBuiltin::BI__builtin_cabsf;
8333 caseBuiltin::BIabs:
8334 caseBuiltin::BIlabs:
8335 caseBuiltin::BIllabs:
8336 caseBuiltin::BIfabsf:
8337 caseBuiltin::BIfabs:
8338 caseBuiltin::BIfabsl:
8339 returnBuiltin::BIcabsf;
8342llvm_unreachable(
"Unable to convert function");
8353 caseBuiltin::BI__builtin_abs:
8354 caseBuiltin::BI__builtin_fabs:
8355 caseBuiltin::BI__builtin_fabsf:
8356 caseBuiltin::BI__builtin_fabsl:
8357 caseBuiltin::BI__builtin_labs:
8358 caseBuiltin::BI__builtin_llabs:
8359 caseBuiltin::BI__builtin_cabs:
8360 caseBuiltin::BI__builtin_cabsf:
8361 caseBuiltin::BI__builtin_cabsl:
8362 caseBuiltin::BIabs:
8363 caseBuiltin::BIlabs:
8364 caseBuiltin::BIllabs:
8365 caseBuiltin::BIfabs:
8366 caseBuiltin::BIfabsf:
8367 caseBuiltin::BIfabsl:
8368 caseBuiltin::BIcabs:
8369 caseBuiltin::BIcabsf:
8370 caseBuiltin::BIcabsl:
8373llvm_unreachable(
"Unknown Builtin type");
8379 unsignedAbsKind,
QualTypeArgType) {
8380 boolEmitHeaderHint =
true;
8381 const char*HeaderName =
nullptr;
8382StringRef FunctionName;
8384FunctionName =
"std::abs";
8386HeaderName =
"cstdlib";
8388HeaderName =
"cmath";
8390llvm_unreachable(
"Invalid Type");
8399 for(
const auto*I : R) {
8402FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8404FDecl = dyn_cast<FunctionDecl>(I);
8419EmitHeaderHint =
false;
8437EmitHeaderHint =
false;
8441}
else if(!R.
empty()) {
8447S.
Diag(
Loc, diag::note_replace_abs_function)
8453 if(!EmitHeaderHint)
8456S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8460template<std::
size_tStrLen>
8462 const char(&Str)[StrLen]) {
8475 autoMatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8476 returnstd::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {
8477return calleeName == name;
8482 caseMathCheck::NaN:
8483 returnMatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8484 "__builtin_nanf16",
"__builtin_nanf128"});
8485 caseMathCheck::Inf:
8486 returnMatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8487 "__builtin_inff16",
"__builtin_inff128"});
8489llvm_unreachable(
"unknown MathCheck");
8493 if(FDecl->
getName() !=
"infinity")
8496 if(
const CXXMethodDecl*MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
8498 if(RDecl->
getName() !=
"numeric_limits")
8515 if(FPO.getNoHonorNaNs() &&
8518 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8519<< 1 << 0 <<
Call->getSourceRange();
8523 if(FPO.getNoHonorInfs() &&
8527 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8528<< 0 << 0 <<
Call->getSourceRange();
8532voidSema::CheckAbsoluteValueFunction(
const CallExpr*
Call,
8534 if(
Call->getNumArgs() != 1)
8539 if(AbsKind == 0 && !IsStdAbs)
8542 QualTypeArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8548StringRef FunctionName =
8550 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8551 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8560 unsignedDiagType = 0;
8566 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8580 if(ArgValueKind == ParamValueKind) {
8585 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8586<< FDecl << ArgType << ParamType;
8588 if(NewAbsKind == 0)
8592 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8601 if(NewAbsKind == 0)
8604 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8605<< FDecl << ParamValueKind << ArgValueKind;
8608 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8612voidSema::CheckMaxUnsignedZero(
const CallExpr*
Call,
8614 if(!
Call|| !FDecl)
return;
8618 if(
Call->getExprLoc().isMacroID())
return;
8621 if(
Call->getNumArgs() != 2)
return;
8624 if(!ArgList)
return;
8625 if(ArgList->size() != 1)
return;
8628 const auto& TA = ArgList->
get(0);
8634 autoIsLiteralZeroArg = [](
const Expr*
E) ->
bool{
8635 const auto*MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8636 if(!MTE)
return false;
8637 const auto*
Num= dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8638 if(!
Num)
return false;
8639 if(
Num->getValue() != 0)
return false;
8643 const Expr*FirstArg =
Call->getArg(0);
8644 const Expr*SecondArg =
Call->getArg(1);
8645 const boolIsFirstArgZero = IsLiteralZeroArg(FirstArg);
8646 const boolIsSecondArgZero = IsLiteralZeroArg(SecondArg);
8649 if(IsFirstArgZero == IsSecondArgZero)
return;
8654 SourceRangeZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8656 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8657<< IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8661 if(IsFirstArgZero) {
8669 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8689 if(!Size->isComparisonOp() && !Size->isLogicalOp())
8693S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8694<< SizeRange << FnName;
8695S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8700S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8711 bool&IsContained) {
8714IsContained =
false;
8727 for(
auto*FD : RD->
fields()) {
8731IsContained =
true;
8740 if(
const auto*Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8741 if(Unary->getKind() == UETT_SizeOf)
8750 if(!
SizeOf->isArgumentType())
8751 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8758 return SizeOf->getTypeOfArgument();
8764structSearchNonTrivialToInitializeField
8769SearchNonTrivialToInitializeField(
const Expr*
E,
Sema&S) :
E(
E), S(S) {}
8773 if(
const auto*AT = asDerived().getContext().getAsArrayType(FT)) {
8774asDerived().visitArray(PDIK, AT, SL);
8778Super::visitWithKind(PDIK, FT, SL);
8793visit(getContext().getBaseElementType(AT), SL);
8798SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8807structSearchNonTrivialToCopyField
8811SearchNonTrivialToCopyField(
const Expr*
E,
Sema&S) :
E(
E), S(S) {}
8815 if(
const auto*AT = asDerived().getContext().getAsArrayType(FT)) {
8816asDerived().visitArray(PCK, AT, SL);
8820Super::visitWithKind(PCK, FT, SL);
8835visit(getContext().getBaseElementType(AT), SL);
8843SearchNonTrivialToCopyField(
E, S).visitStruct(RT,
SourceLocation());
8858 if(
const auto*BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8859 if(BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8883 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8885 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8886 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8892 if(BId != Builtin::BImemset && BId != Builtin::BIbzero)
8895 const Expr*SizeArg =
8896 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8898 autoisLiteralZero = [](
const Expr*
E) {
8899 return(isa<IntegerLiteral>(
E) &&
8900cast<IntegerLiteral>(
E)->getValue() == 0) ||
8901(isa<CharacterLiteral>(
E) &&
8902cast<CharacterLiteral>(
E)->getValue() == 0);
8908 if(isLiteralZero(SizeArg) &&
8915 if(BId == Builtin::BIbzero ||
8918S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8919S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8920}
else if(!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8921S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8922S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8930 if(BId == Builtin::BImemset &&
8934S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8935S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8940voidSema::CheckMemaccessArguments(
const CallExpr*
Call,
8947 unsignedExpectedNumArgs =
8948(BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8949 if(
Call->getNumArgs() < ExpectedNumArgs)
8952 unsignedLastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8953BId == Builtin::BIstrndup ? 1 : 2);
8955(BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8956 const Expr*LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8959 Call->getBeginLoc(),
Call->getRParenLoc()))
8968llvm::FoldingSetNodeID SizeOfArgID;
8973 QualTypeFirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8977 for(
unsignedArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8978 const Expr*Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
9000 if(SizeOfArgID == llvm::FoldingSetNodeID())
9002llvm::FoldingSetNodeID DestID;
9004 if(DestID == SizeOfArgID) {
9007 unsignedActionIdx = 0;
9008StringRef ReadableName = FnName->
getName();
9010 if(
const UnaryOperator*UnaryOp = dyn_cast<UnaryOperator>(Dest))
9011 if(UnaryOp->getOpcode() == UO_AddrOf)
9025 if(
SM.isMacroArgExpansion(SL)) {
9027SL =
SM.getSpellingLoc(SL);
9029 SM.getSpellingLoc(DSR.
getEnd()));
9031 SM.getSpellingLoc(SSR.
getEnd()));
9035 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
9042 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9057 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9058<< FnName << SizeOfArgTy << ArgIdx
9076 unsignedOperationType = 0;
9077 const boolIsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9080 if(ArgIdx != 0 || IsCmp) {
9081 if(BId == Builtin::BImemcpy)
9083 else if(BId == Builtin::BImemmove)
9090 PDiag(diag::warn_dyn_class_memaccess)
9091<< (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9092<< IsContained << ContainedRD << OperationType
9093<<
Call->getCallee()->getSourceRange());
9095BId != Builtin::BImemset)
9098 PDiag(diag::warn_arc_object_memaccess)
9099<< ArgIdx << FnName << PointeeTy
9100<<
Call->getCallee()->getSourceRange());
9107 boolMayBeTriviallyCopyableCXXRecord =
9109RT->desugar().isTriviallyCopyableType(
Context);
9111 if((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9112RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9114 PDiag(diag::warn_cstruct_memaccess)
9115<< ArgIdx << FnName << PointeeTy << 0);
9116SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9117}
else if((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9118!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9122 PDiag(diag::warn_cxxstruct_memaccess)
9123<< FnName << PointeeTy);
9124}
else if((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9125RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9127 PDiag(diag::warn_cstruct_memaccess)
9128<< ArgIdx << FnName << PointeeTy << 1);
9129SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9130}
else if((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9131!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9135 PDiag(diag::warn_cxxstruct_memaccess)
9136<< FnName << PointeeTy);
9145 PDiag(diag::note_bad_memaccess_silence)
9165 if(isa<IntegerLiteral>(RHS))
9167 else if(isa<IntegerLiteral>(LHS))
9181 if(CAT->getZExtSize() <= 1)
9189voidSema::CheckStrlcpycatArguments(
const CallExpr*
Call,
9193 unsignedNumArgs =
Call->getNumArgs();
9194 if((NumArgs != 3) && (NumArgs != 4))
9199 const Expr*CompareWithSrc =
nullptr;
9202 Call->getBeginLoc(),
Call->getRParenLoc()))
9207CompareWithSrc = Ex;
9210 if(
const CallExpr*SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9211 if(SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9212SizeCall->getNumArgs() == 1)
9217 if(!CompareWithSrc)
9224 const DeclRefExpr*SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9228 const DeclRefExpr*CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9229 if(!CompareWithSrcDRE ||
9233 const Expr*OriginalSizeArg =
Call->getArg(2);
9234 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9241 const Expr*DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9246llvm::raw_svector_ostream
OS(sizeString);
9251 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9258 if(
const DeclRefExpr*D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9259 if(
const DeclRefExpr*D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9260 returnD1->getDecl() == D2->getDecl();
9265 if(
const CallExpr*CE = dyn_cast<CallExpr>(
E)) {
9274voidSema::CheckStrncatArguments(
const CallExpr*CE,
9289 unsignedPatternType = 0;
9297}
else if(
const BinaryOperator*BE = dyn_cast<BinaryOperator>(LenArg)) {
9298 if(BE->getOpcode() == BO_Sub) {
9311 if(PatternType == 0)
9320 if(
SM.isMacroArgExpansion(SL)) {
9321SL =
SM.getSpellingLoc(SL);
9323 SM.getSpellingLoc(SR.
getEnd()));
9330 if(!isKnownSizeArray) {
9331 if(PatternType == 1)
9332 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9334 Diag(SL, diag::warn_strncat_src_size) << SR;
9338 if(PatternType == 1)
9339 Diag(SL, diag::warn_strncat_large_size) << SR;
9341 Diag(SL, diag::warn_strncat_src_size) << SR;
9344llvm::raw_svector_ostream
OS(sizeString);
9352 Diag(SL, diag::note_strncat_wrong_size)
9357voidCheckFreeArgumentsOnLvalue(
Sema&S,
conststd::string &CalleeName,
9359 if(isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9361<< CalleeName << 0
<< cast<NamedDecl>(
D);
9366voidCheckFreeArgumentsAddressof(
Sema&S,
conststd::string &CalleeName,
9368 if(
const auto*Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9369 const Decl*
D= Lvalue->getDecl();
9370 if(isa<DeclaratorDecl>(
D))
9371 if(!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9372 returnCheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9375 if(
const auto*Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9376 returnCheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9377Lvalue->getMemberDecl());
9380voidCheckFreeArgumentsPlus(
Sema&S,
conststd::string &CalleeName,
9382 const auto*Lambda = dyn_cast<LambdaExpr>(
9387S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9388<< CalleeName << 2
;
9391voidCheckFreeArgumentsStackArray(
Sema&S,
conststd::string &CalleeName,
9393 const auto*Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9394 if(Var ==
nullptr)
9398<< CalleeName << 0
<< Var;
9401voidCheckFreeArgumentsCast(
Sema&S,
conststd::string &CalleeName,
9404llvm::raw_svector_ostream OS(SizeString);
9407 if(Kind == clang::CK_BitCast &&
9408!
Cast->getSubExpr()->getType()->isFunctionPointerType())
9410 if(Kind == clang::CK_IntegralToPointer &&
9411!isa<IntegerLiteral>(
9412 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9415 switch(
Cast->getCastKind()) {
9416 caseclang::CK_BitCast:
9417 caseclang::CK_IntegralToPointer:
9418 caseclang::CK_FunctionToPointerDecay:
9427S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9428<< CalleeName << 0
<< OS.str();
9432voidSema::CheckFreeArguments(
const CallExpr*
E) {
9433 conststd::string CalleeName =
9434cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9438 if(
const auto*UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9440 caseUnaryOperator::Opcode::UO_AddrOf:
9441 returnCheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9442 caseUnaryOperator::Opcode::UO_Plus:
9443 returnCheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9448 if(
const auto*Lvalue = dyn_cast<DeclRefExpr>(Arg))
9450 returnCheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9452 if(
const auto*
Label= dyn_cast<AddrLabelExpr>(Arg)) {
9453 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9454<< CalleeName << 0
<<
Label->getLabel()->getIdentifier();
9458 if(isa<BlockExpr>(Arg)) {
9460<< CalleeName << 1
;
9465 if(
const auto*Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9466 returnCheckFreeArgumentsCast(*
this, CalleeName, Cast);
9470Sema::CheckReturnValExpr(
Expr*RetValExp,
QualTypelhsType,
9476 if(((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9479 Diag(ReturnLoc, diag::warn_null_ret)
9489 if(Op == OO_New || Op == OO_Array_New) {
9494 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9500 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9517 autogetCastAndLiteral = [&FPLiteral, &FPCast](
Expr*L,
Expr*R) {
9518FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9520 returnFPLiteral && FPCast;
9523 if(getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9529llvm::APFloat TargetC = FPLiteral->
getValue();
9531llvm::APFloat::rmNearestTiesToEven, &Lossy);
9535 Diag(
Loc, diag::warn_float_compare_literal)
9536<< (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9549 if(
auto*DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9550 if(
auto*DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9551 if(DRL->getDecl() == DRR->getDecl())
9559 if(
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9563 if(
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9568 if(
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9569 if(CL->getBuiltinCallee())
9572 if(
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9573 if(CR->getBuiltinCallee())
9577 Diag(
Loc, diag::warn_floatingpoint_eq)
9598IntRange(
unsignedWidth,
boolNonNegative)
9599: Width(Width), NonNegative(NonNegative) {}
9602 unsignedvalueBits()
const{
9603 returnNonNegative ? Width : Width - 1;
9607 staticIntRange forBoolType() {
9608 returnIntRange(1,
true);
9613 returnforValueOfCanonicalType(
C,
9618 staticIntRange forValueOfCanonicalType(
ASTContext&
C,
const Type*
T) {
9621 if(
const VectorType*VT = dyn_cast<VectorType>(
T))
9622 T= VT->getElementType().getTypePtr();
9623 if(
const ComplexType*CT = dyn_cast<ComplexType>(
T))
9624 T= CT->getElementType().getTypePtr();
9625 if(
const AtomicType*AT = dyn_cast<AtomicType>(
T))
9626 T= AT->getValueType().getTypePtr();
9628 if(!
C.getLangOpts().CPlusPlus) {
9630 if(
const EnumType*ET = dyn_cast<EnumType>(
T))
9631 T= ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9632}
else if(
const EnumType*ET = dyn_cast<EnumType>(
T)) {
9637 if(
Enum->isFixed()) {
9638 returnIntRange(
C.getIntWidth(
QualType(
T, 0)),
9639!ET->isSignedIntegerOrEnumerationType());
9642 unsignedNumPositive =
Enum->getNumPositiveBits();
9643 unsignedNumNegative =
Enum->getNumNegativeBits();
9645 if(NumNegative == 0)
9646 returnIntRange(NumPositive,
true);
9648 returnIntRange(std::max(NumPositive + 1, NumNegative),
9652 if(
const auto*EIT = dyn_cast<BitIntType>(
T))
9653 returnIntRange(EIT->getNumBits(), EIT->isUnsigned());
9666 staticIntRange forTargetOfCanonicalType(
ASTContext&
C,
const Type*
T) {
9669 if(
const VectorType*VT = dyn_cast<VectorType>(
T))
9670 T= VT->getElementType().getTypePtr();
9671 if(
const ComplexType*CT = dyn_cast<ComplexType>(
T))
9672 T= CT->getElementType().getTypePtr();
9673 if(
const AtomicType*AT = dyn_cast<AtomicType>(
T))
9674 T= AT->getValueType().getTypePtr();
9675 if(
const EnumType*ET = dyn_cast<EnumType>(
T))
9676 T=
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9678 if(
const auto*EIT = dyn_cast<BitIntType>(
T))
9679 returnIntRange(EIT->getNumBits(), EIT->isUnsigned());
9688 staticIntRange join(IntRange L, IntRange R) {
9689 bool Unsigned= L.NonNegative && R.NonNegative;
9690 returnIntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9691L.NonNegative && R.NonNegative);
9695 staticIntRange bit_and(IntRange L, IntRange R) {
9696 unsignedBits = std::max(L.Width, R.Width);
9697 boolNonNegative =
false;
9698 if(L.NonNegative) {
9699Bits = std::min(Bits, L.Width);
9700NonNegative =
true;
9702 if(R.NonNegative) {
9703Bits = std::min(Bits, R.Width);
9704NonNegative =
true;
9706 returnIntRange(Bits, NonNegative);
9710 staticIntRange sum(IntRange L, IntRange R) {
9711 bool Unsigned= L.NonNegative && R.NonNegative;
9712 returnIntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9717 staticIntRange difference(IntRange L, IntRange R) {
9721 boolCanWiden = !L.NonNegative || !R.NonNegative;
9722 bool Unsigned= L.NonNegative && R.Width == 0;
9723 returnIntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9729 staticIntRange product(IntRange L, IntRange R) {
9733 boolCanWiden = !L.NonNegative && !R.NonNegative;
9734 bool Unsigned= L.NonNegative && R.NonNegative;
9735 returnIntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9740 staticIntRange rem(IntRange L, IntRange R) {
9744 returnIntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9752 unsignedMaxWidth) {
9753 if(value.isSigned() && value.isNegative())
9754 returnIntRange(value.getSignificantBits(),
false);
9756 if(value.getBitWidth() > MaxWidth)
9757value = value.trunc(MaxWidth);
9761 returnIntRange(value.getActiveBits(),
true);
9765 unsignedMaxWidth) {
9766 if(result.
isInt())
9773R = IntRange::join(R, El);
9781 returnIntRange::join(R, I);
9796Ty = AtomicRHS->getValueType();
9815 boolInConstantContext,
9827 if(
const auto*CE = dyn_cast<ImplicitCastExpr>(
E)) {
9828 if(CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9829 return TryGetExprRange(
C, CE->getSubExpr(), MaxWidth, InConstantContext,
9832IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9834 boolisIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9835CE->getCastKind() == CK_BooleanToSignedIntegral;
9839 returnOutputTypeRange;
9842 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
9843InConstantContext, Approximate);
9845 returnstd::nullopt;
9848 if(SubRange->Width >= OutputTypeRange.Width)
9849 returnOutputTypeRange;
9853 returnIntRange(SubRange->Width,
9854SubRange->NonNegative || OutputTypeRange.NonNegative);
9857 if(
const auto*CO = dyn_cast<ConditionalOperator>(
E)) {
9860 if(CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9862 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
9863InConstantContext, Approximate);
9868 Expr*TrueExpr = CO->getTrueExpr();
9870 returnstd::nullopt;
9872std::optional<IntRange> L =
9875 returnstd::nullopt;
9877 Expr*FalseExpr = CO->getFalseExpr();
9879 returnstd::nullopt;
9881std::optional<IntRange> R =
9882 TryGetExprRange(
C, FalseExpr, MaxWidth, InConstantContext, Approximate);
9884 returnstd::nullopt;
9886 returnIntRange::join(*L, *R);
9889 if(
const auto*BO = dyn_cast<BinaryOperator>(
E)) {
9890IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9892 switch(BO->getOpcode()) {
9894llvm_unreachable(
"builtin <=> should have class type");
9905 returnIntRange::forBoolType();
9934Combine = IntRange::bit_and;
9942= dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9943 if(I->getValue() == 1) {
9944IntRange R = IntRange::forValueOfType(
C,
GetExprType(
E));
9945 returnIntRange(R.Width,
true);
9955 caseBO_ShrAssign: {
9957 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
9959 returnstd::nullopt;
9963 if(std::optional<llvm::APSInt> shift =
9964BO->getRHS()->getIntegerConstantExpr(
C)) {
9965 if(shift->isNonNegative()) {
9966 if(shift->uge(L->Width))
9967L->Width = (L->NonNegative ? 0 : 1);
9969L->Width -= shift->getZExtValue();
9983Combine = IntRange::sum;
9987 if(BO->getLHS()->getType()->isPointerType())
9990Combine = IntRange::difference;
9995Combine = IntRange::product;
10004 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
10006 returnstd::nullopt;
10009 if(std::optional<llvm::APSInt> divisor =
10010BO->getRHS()->getIntegerConstantExpr(
C)) {
10011 unsigned log2= divisor->logBase2();
10012 if(
log2>= L->Width)
10013L->Width = (L->NonNegative ? 0 : 1);
10015L->Width = std::min(L->Width -
log2, MaxWidth);
10023 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
10025 returnstd::nullopt;
10027 returnIntRange(L->Width, L->NonNegative && R->NonNegative);
10031Combine = IntRange::rem;
10043 unsignedopWidth =
C.getIntWidth(
T);
10045InConstantContext, Approximate);
10047 returnstd::nullopt;
10050InConstantContext, Approximate);
10052 returnstd::nullopt;
10054IntRange
C= Combine(*L, *R);
10056 C.Width = std::min(
C.Width, MaxWidth);
10060 if(
const auto*UO = dyn_cast<UnaryOperator>(
E)) {
10061 switch(UO->getOpcode()) {
10064 returnIntRange::forBoolType();
10072 return TryGetExprRange(
C, UO->getSubExpr(), MaxWidth, InConstantContext,
10077 if(
const auto*OVE = dyn_cast<OpaqueValueExpr>(
E))
10078 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10082 returnIntRange(BitField->getBitWidthValue(),
10083BitField->getType()->isUnsignedIntegerOrEnumerationType());
10086 returnstd::nullopt;
10092 boolInConstantContext,
10093 boolApproximate) {
10102 constllvm::fltSemantics &Src,
10103 constllvm::fltSemantics &Tgt) {
10104llvm::APFloat truncated = value;
10107truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10108truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10110 returntruncated.bitwiseIsEqual(value);
10119 constllvm::fltSemantics &Src,
10120 constllvm::fltSemantics &Tgt) {
10137 boolIsListInit =
false);
10143 if(isa<EnumConstantDecl>(DR->getDecl()))
10153 returnMacroName !=
"YES"&& MacroName !=
"NO"&&
10154MacroName !=
"true"&& MacroName !=
"false";
10177structPromotedRange {
10179llvm::APSInt PromotedMin;
10181llvm::APSInt PromotedMax;
10183PromotedRange(IntRange R,
unsignedBitWidth,
bool Unsigned) {
10185PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
10186 else if(R.Width >= BitWidth && !
Unsigned) {
10190PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
10191PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
10193PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10194.extOrTrunc(BitWidth);
10195PromotedMin.setIsUnsigned(
Unsigned);
10197PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10198.extOrTrunc(BitWidth);
10199PromotedMax.setIsUnsigned(
Unsigned);
10204 boolisContiguous()
const{
returnPromotedMin <= PromotedMax; }
10214InRangeFlag = 0x40,
10217 Min=
LE| InRangeFlag,
10219 Max=
GE| InRangeFlag,
10222OnlyValue =
LE|
GE|
EQ| InRangeFlag,
10227assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10228 Value.isUnsigned() == PromotedMin.isUnsigned());
10229 if(!isContiguous()) {
10230assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10231 if(
Value.isMinValue())
return Min;
10232 if(
Value.isMaxValue())
return Max;
10238 switch(llvm::APSInt::compareValues(
Value, PromotedMin)) {
10239 case-1:
return Less;
10240 case0:
returnPromotedMin == PromotedMax ? OnlyValue :
Min;
10242 switch(llvm::APSInt::compareValues(
Value, PromotedMax)) {
10244 case0:
return Max;
10249llvm_unreachable(
"impossible compare result");
10252 staticstd::optional<StringRef>
10254 if(Op == BO_Cmp) {
10256 if(ConstantOnRHS) std::swap(LTFlag, GTFlag);
10258 if(R & EQ)
returnStringRef(
"'std::strong_ordering::equal'");
10259 if(R & LTFlag)
returnStringRef(
"'std::strong_ordering::less'");
10260 if(R & GTFlag)
returnStringRef(
"'std::strong_ordering::greater'");
10261 returnstd::nullopt;
10268}
else if(Op == BO_NE) {
10272 if((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10279 if(Op == BO_GE || Op == BO_LE)
10280std::swap(TrueFlag, FalseFlag);
10283 returnStringRef(
"true");
10285 returnStringRef(
"false");
10286 returnstd::nullopt;
10294 if(ICE->getCastKind() != CK_IntegralCast &&
10295ICE->getCastKind() != CK_NoOp)
10297 E= ICE->getSubExpr();
10306 enumConstantValueKind {
10311 if(
auto*BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10312 returnBL->getValue() ? ConstantValueKind::LiteralTrue
10313: ConstantValueKind::LiteralFalse;
10314 returnConstantValueKind::Miscellaneous;
10319 constllvm::APSInt &
Value,
10320 boolRhsConstant) {
10342 if(!OtherValueRange)
10347OtherT = AT->getValueType();
10348IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10352 boolIsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10358 boolOtherIsBooleanDespiteType =
10360 if(OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10361OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
10365PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
10366 Value.isUnsigned());
10367 autoCmp = OtherPromotedValueRange.compare(
Value);
10368 auto Result= PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10374 boolTautologicalTypeCompare =
false;
10376PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10377 Value.isUnsigned());
10378 autoTypeCmp = OtherPromotedTypeRange.compare(
Value);
10379 if(
auto TypeResult= PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10381TautologicalTypeCompare =
true;
10389 if(!TautologicalTypeCompare && OtherValueRange->Width == 0)
10398 boolInRange = Cmp & PromotedRange::InRangeFlag;
10404 if(
Other->refersToBitField() && InRange &&
Value== 0 &&
10405 Other->getType()->isUnsignedIntegerOrEnumerationType())
10406TautologicalTypeCompare =
true;
10411 if(
const DeclRefExpr*DR = dyn_cast<DeclRefExpr>(Constant))
10412ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10416llvm::raw_svector_ostream OS(PrettySourceValue);
10418OS <<
'\''<< *ED <<
"' ("<<
Value<<
")";
10419}
else if(
auto*BL = dyn_cast<ObjCBoolLiteralExpr>(
10421OS << (BL->getValue() ?
"YES":
"NO");
10426 if(!TautologicalTypeCompare) {
10427S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10428<< RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
10429<<
E->getOpcodeStr() << OS.str() << *
Result 10434 if(IsObjCSignedCharBool) {
10436S.
PDiag(diag::warn_tautological_compare_objc_bool)
10437<< OS.str() << *
Result);
10444 if(!InRange ||
Other->isKnownToHaveBooleanValue()) {
10447 E->getOperatorLoc(),
E,
10448S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10449: diag::warn_tautological_bool_compare)
10451<< OtherIsBooleanDespiteType << *
Result 10458? diag::warn_unsigned_enum_always_true_comparison
10459: IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10460: diag::warn_unsigned_always_true_comparison)
10461: diag::warn_tautological_constant_compare;
10464<< RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result 10494 Expr*LHS =
E->getLHS();
10495 Expr*RHS =
E->getRHS();
10498std::optional<llvm::APSInt> RHSValue =
10500std::optional<llvm::APSInt> LHSValue =
10504 if(RHSValue && LHSValue)
10508 if((
bool)RHSValue ^ (
bool)LHSValue) {
10510 const boolRhsConstant = (
bool)RHSValue;
10511 Expr*Const = RhsConstant ? RHS : LHS;
10512 Expr*
Other= RhsConstant ? LHS : RHS;
10513 constllvm::APSInt &
Value= RhsConstant ? *RHSValue : *LHSValue;
10536 if(
const auto*TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10538 if(
const auto*TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10544 Expr*signedOperand, *unsignedOperand;
10547 "unsigned comparison between two signed integer expressions?");
10548signedOperand = LHS;
10549unsignedOperand = RHS;
10551signedOperand = RHS;
10552unsignedOperand = LHS;
10558std::optional<IntRange> signedRange =
10570 if(signedRange->NonNegative)
10577 if(
E->isEqualityOp()) {
10582 if(!unsignedRange)
10587assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
10589 if(unsignedRange->Width < comparisonWidth)
10594S.
PDiag(diag::warn_mixed_sign_comparison)
10622S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10623<< BitfieldEnumDecl;
10630 Init->isValueDependent() ||
10631 Init->isTypeDependent())
10634 Expr*OriginalInit =
Init->IgnoreParenImpCasts();
10657 unsignedDiagID = 0;
10658 if(SignedEnum && !SignedBitfield) {
10659DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10660}
else if(SignedBitfield && !SignedEnum &&
10662DiagID = diag::warn_signed_bitfield_enum_conversion;
10666S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10671<< SignedEnum << TypeRange;
10682 if(BitsNeeded > FieldWidth) {
10684S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10696 unsignedOriginalWidth =
Value.getBitWidth();
10702 boolOneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value== 1;
10703 if(OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10710 if(!
Value.isSigned() ||
Value.isNegative())
10711 if(
UnaryOperator*UO = dyn_cast<UnaryOperator>(OriginalInit))
10712 if(UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10713OriginalWidth =
Value.getSignificantBits();
10715 if(OriginalWidth <= FieldWidth)
10719llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10723TruncatedValue = TruncatedValue.extend(OriginalWidth);
10724 if(llvm::APSInt::isSameValue(
Value, TruncatedValue))
10728std::string PrettyTrunc =
toString(TruncatedValue, 10);
10730S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10731? diag::warn_impcast_single_bit_bitield_precision_constant
10732: diag::warn_impcast_bitfield_precision_constant)
10733<< PrettyValue << PrettyTrunc << OriginalInit->
getType()
10734<<
Init->getSourceRange();
10749 E->getOperatorLoc())) {
10752 E->getOperatorLoc());
10760S.
Diag(
E->getRHS()->
getBeginLoc(), diag::warn_atomic_implicit_seq_cst);
10766 boolpruneControlFlow =
false) {
10767 if(pruneControlFlow) {
10781 unsigneddiag,
boolpruneControlFlow =
false) {
10794 if(UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10797 const boolIsLiteral =
10798isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10800llvm::APFloat
Value(0.0);
10806 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10811diag::warn_impcast_float_integer, PruneWarnings);
10814 boolisExact =
false;
10818llvm::APFloat::opStatus
Result=
Value.convertToInteger(
10819IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10827 unsignedprecision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10828precision = (precision * 59 + 195) / 196;
10829 Value.toString(PrettySourceValue, precision);
10833 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10834<< PrettySourceValue);
10837 if(
Result== llvm::APFloat::opOK && isExact) {
10838 if(IsLiteral)
return;
10845 if(!IsBool &&
Result== llvm::APFloat::opInvalidOp)
10847S,
E,
T, CContext,
10848IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10849: diag::warn_impcast_float_to_integer_out_of_range,
10852 unsignedDiagID = 0;
10855DiagID = diag::warn_impcast_literal_float_to_integer;
10856}
else if(IntegerValue == 0) {
10857 if(
Value.isZero()) {
10859diag::warn_impcast_float_integer, PruneWarnings);
10862DiagID = diag::warn_impcast_float_to_integer_zero;
10864 if(IntegerValue.isUnsigned()) {
10865 if(!IntegerValue.isMaxValue()) {
10867diag::warn_impcast_float_integer, PruneWarnings);
10870 if(!IntegerValue.isMaxSignedValue() &&
10871!IntegerValue.isMinSignedValue()) {
10873diag::warn_impcast_float_integer, PruneWarnings);
10877DiagID = diag::warn_impcast_float_to_integer;
10882PrettyTargetValue =
Value.isZero() ?
"false":
"true";
10884IntegerValue.toString(PrettyTargetValue);
10886 if(PruneWarnings) {
10889<<
E->
getType() <<
T.getUnqualifiedType()
10890<< PrettySourceValue << PrettyTargetValue
10894<<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10902assert(isa<CompoundAssignOperator>(
E) &&
10903 "Must be compound assignment operation");
10909S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10913 const auto*RBT = cast<CompoundAssignOperator>(
E)
10914->getComputationResultType()
10921 if(ResultBT->isInteger())
10923 E->
getExprLoc(), diag::warn_impcast_float_integer);
10925 if(!ResultBT->isFloatingPoint())
10934diag::warn_impcast_float_result_precision);
10939 if(!
Range.Width)
return "0";
10941llvm::APSInt ValueInRange =
Value;
10942ValueInRange.setIsSigned(!
Range.NonNegative);
10943ValueInRange = ValueInRange.trunc(
Range.Width);
10944 return toString(ValueInRange, 10);
10948 if(!isa<ImplicitCastExpr>(Ex))
10953 const Type*Source =
10955 if(
Target->isDependentType())
10959dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10960 const Type*BoolCandidateType = ToBool ?
Target: Source;
10969 for(
unsignedi = 0; i < NumArgs; ++i) {
10974 boolIsSwapped = ((i > 0) &&
10976IsSwapped |= ((i < (NumArgs - 1)) &&
10982diag::warn_impcast_floating_point_to_bool);
10989 if(S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10994 if(isa<CallExpr>(
E))
10999 boolIsGNUNullExpr = isa<GNUNullExpr>(NewE);
11001 if(!IsGNUNullExpr && !HasNullPtrType)
11021 if(MacroName ==
"NULL")
11029S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
11043 const charFirstLiteralCharacter =
11045 if(FirstLiteralCharacter ==
'0')
11052 const charFirstContextCharacter =
11054 if(FirstContextCharacter ==
'{')
11062 const auto*IL = dyn_cast<IntegerLiteral>(
E);
11064 if(
auto*UO = dyn_cast<UnaryOperator>(
E)) {
11065 if(UO->getOpcode() == UO_Minus)
11066 returndyn_cast<IntegerLiteral>(UO->getSubExpr());
11077 if(
const auto*BO = dyn_cast<BinaryOperator>(
E)) {
11081 if(Opc == BO_Shl) {
11084 if(LHS && LHS->getValue() == 0)
11085S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11087RHS->getValue().isNonNegative() &&
11089S.
Diag(ExprLoc, diag::warn_left_shift_always)
11090<< (
Result.Val.getInt() != 0);
11092S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11096 if(
const auto*CO = dyn_cast<ConditionalOperator>(
E)) {
11101 if((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11102(RHS->getValue() == 0 || RHS->getValue() == 1))
11105 if(LHS->getValue() != 0 && RHS->getValue() != 0)
11106S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11111 bool*ICContext,
boolIsListInit) {
11116 if(Source ==
Target)
return;
11117 if(
Target->isDependentType())
return;
11131 if(
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11132 if(isa<StringLiteral>(
E))
11137diag::warn_impcast_string_literal_to_bool);
11138 if(isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11139isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11143diag::warn_impcast_objective_c_literal_to_bool);
11158 if(
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
11160 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11169 if(
auto*ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11171 else if(
auto*DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11175 if(isa<VectorType>(Source)) {
11176 if(
Target->isSveVLSBuiltinType() &&
11183 if(
Target->isRVVVLSBuiltinType() &&
11190 if(!isa<VectorType>(
Target)) {
11193 return DiagnoseImpCast(*
this,
E,
T, CC, diag::warn_impcast_vector_scalar);
11200diag::warn_hlsl_impcast_vector_truncation);
11209Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11210 Target= cast<VectorType>(
Target)->getElementType().getTypePtr();
11212 if(
autoVecTy = dyn_cast<VectorType>(
Target))
11213 Target= VecTy->getElementType().getTypePtr();
11216 if(isa<ComplexType>(Source)) {
11217 if(!isa<ComplexType>(
Target)) {
11223? diag::err_impcast_complex_scalar
11224: diag::warn_impcast_complex_scalar);
11227Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11228 Target= cast<ComplexType>(
Target)->getElementType().getTypePtr();
11231 const BuiltinType*SourceBT = dyn_cast<BuiltinType>(Source);
11284 else if(Order < 0) {
11294 if(TargetBT && TargetBT->
isInteger()) {
11309 if(
Target->isBooleanType() && isa<CallExpr>(
E)) {
11314 if(
unsignedNumArgs = CEx->
getNumArgs()) {
11317 if(isa<ImplicitCastExpr>(LastA) &&
11321diag::warn_impcast_floating_point_to_bool);
11330 if(
Target->isUnsaturatedFixedPointType()) {
11334llvm::APFixedPoint
Value=
Result.Val.getFixedPoint();
11339 PDiag(diag::warn_impcast_fixed_point_range)
11340<<
Value.toString() <<
T 11346}
else if(
Target->isIntegerType()) {
11350llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11353llvm::APSInt IntResult = FXResult.convertToInt(
11359 PDiag(diag::warn_impcast_fixed_point_range)
11360<< FXResult.toString() <<
T 11367}
else if(
Target->isUnsaturatedFixedPointType()) {
11375llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11380 PDiag(diag::warn_impcast_fixed_point_range)
11401 unsigned intSourcePrecision =
SourceRange->Width;
11405 unsigned intTargetPrecision = llvm::APFloatBase::semanticsPrecision(
11408 if(SourcePrecision > 0 && TargetPrecision > 0 &&
11409SourcePrecision > TargetPrecision) {
11411 if(std::optional<llvm::APSInt> SourceInt =
11416llvm::APFloat TargetFloatValue(
11418llvm::APFloat::opStatus ConversionStatus =
11419TargetFloatValue.convertFromAPInt(
11421llvm::APFloat::rmNearestTiesToEven);
11423 if(ConversionStatus != llvm::APFloat::opOK) {
11425SourceInt->toString(PrettySourceValue, 10);
11427TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11431 PDiag(diag::warn_impcast_integer_float_precision_constant)
11432<< PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T 11438diag::warn_impcast_integer_float_precision);
11447 if(
Target->isBooleanType())
11455 if(
Target->isSpecificBuiltinType(BuiltinType::Bool))
11461 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11466 if(!LikelySourceRange)
11469IntRange SourceTypeRange =
11470IntRange::forTargetOfCanonicalType(
Context, Source);
11471IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11473 if(LikelySourceRange->Width > TargetRange.Width) {
11479llvm::APSInt
Value(32);
11489 PDiag(diag::warn_impcast_integer_precision_constant)
11490<< PrettySourceValue << PrettyTargetValue
11504diag::warn_impcast_integer_precision);
11507 if(TargetRange.Width > SourceTypeRange.Width) {
11508 if(
auto*UO = dyn_cast<UnaryOperator>(
E))
11509 if(UO->getOpcode() == UO_Minus)
11511 if(
Target->isUnsignedIntegerType())
11513diag::warn_impcast_high_order_zero_bits);
11514 if(
Target->isSignedIntegerType())
11516diag::warn_impcast_nonnegative_result);
11520 if(TargetRange.Width == LikelySourceRange->Width &&
11521!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11536 PDiag(diag::warn_impcast_integer_precision_constant)
11537<< PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T 11546 if((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11547((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
11548(!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11549LikelySourceRange->Width == TargetRange.Width))) {
11553 if(SourceBT && SourceBT->
isInteger() && TargetBT &&
11559 unsignedDiagID = diag::warn_impcast_integer_sign;
11567DiagID = diag::warn_impcast_integer_sign_conditional;
11568*ICContext =
true;
11582 if(SourceEnum->getDecl()->hasNameForLinkage() &&
11583TargetEnum->getDecl()->hasNameForLinkage() &&
11584SourceEnum != TargetEnum) {
11589diag::warn_impcast_different_enum_types);
11603 if(
auto*CO = dyn_cast<AbstractConditionalOperator>(
E))
11615 Expr*TrueExpr =
E->getTrueExpr();
11616 if(
auto*BCO = dyn_cast<BinaryConditionalOperator>(
E))
11617TrueExpr = BCO->getCommon();
11619 boolSuspicious =
false;
11628 if(!Suspicious)
return;
11631 if(!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11638Suspicious =
false;
11643 E->
getType(), CC, &Suspicious);
11660structAnalyzeImplicitConversionsWorkItem {
11670 Sema&S, AnalyzeImplicitConversionsWorkItem Item,
11672 Expr*OrigE = Item.E;
11681 boolIsListInit = Item.IsListInit ||
11682(isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11687 Expr*SourceExpr =
E;
11692 if(
auto*OVE = dyn_cast<OpaqueValueExpr>(
E))
11693 if(
auto*Src = OVE->getSourceExpr())
11696 if(
const auto*UO = dyn_cast<UnaryOperator>(SourceExpr))
11697 if(UO->getOpcode() == UO_Not &&
11698UO->getSubExpr()->isKnownToHaveBooleanValue())
11699S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11703 if(
const auto*BO = dyn_cast<BinaryOperator>(SourceExpr))
11704 if((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11705BO->getLHS()->isKnownToHaveBooleanValue() &&
11706BO->getRHS()->isKnownToHaveBooleanValue() &&
11707BO->getLHS()->HasSideEffects(S.
Context) &&
11708BO->getRHS()->HasSideEffects(S.
Context)) {
11719 if(SR.str() ==
"&"|| SR.str() ==
"|") {
11721S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11722<< (BO->getOpcode() == BO_And ?
"&":
"|")
11725BO->getOperatorLoc(),
11726(BO->getOpcode() == BO_And ?
"&&":
"||"));
11727S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11733 if(
auto*CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11739 if(
CallExpr*
Call= dyn_cast<CallExpr>(SourceExpr))
11745 if(SourceExpr->
getType() !=
T)
11754 for(
auto*SE : POE->semantics())
11755 if(
auto*OVE = dyn_cast<OpaqueValueExpr>(SE))
11756WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11760 if(
auto*CE = dyn_cast<ExplicitCastExpr>(
E)) {
11764WorkList.push_back({
E, CC, IsListInit});
11768 if(
auto*OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
11769WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
11773 if(OutArgE->isInOut())
11774WorkList.push_back(
11775{OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
11776WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
11782 if(BO->isComparisonOp())
11786 if(BO->getOpcode() == BO_Assign)
11789 if(BO->isAssignmentOp())
11797 if(isa<StmtExpr>(
E))
return;
11800 if(isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11805 boolIsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11807 Expr*ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11811 if(
auto*CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11812 if(ChildExpr == CSE->getOperand())
11818 if(IsLogicalAndOperator &&
11823WorkList.push_back({ChildExpr, CC, IsListInit});
11828 if(!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11832 if(!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11837 if(
U->getOpcode() == UO_LNot) {
11839}
else if(
U->getOpcode() != UO_AddrOf) {
11840 if(
U->getSubExpr()->getType()->isAtomicType())
11841S.
Diag(
U->getSubExpr()->getBeginLoc(),
11842diag::warn_atomic_implicit_seq_cst);
11851 boolIsListInit
) {
11853WorkList.push_back({OrigE, CC, IsListInit});
11854 while(!WorkList.empty())
11866 if(
const DeclRefExpr*DRE = dyn_cast<DeclRefExpr>(
E)) {
11869}
else if(
const MemberExpr*M = dyn_cast<MemberExpr>(
E)) {
11870 if(!M->getMemberDecl()->getType()->isReferenceType())
11872}
else if(
const CallExpr*
Call= dyn_cast<CallExpr>(
E)) {
11873 if(!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11875FD =
Call->getDirectCallee();
11884SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11898 if(
SM.isMacroBodyExpansion(
Loc))
11900 Loc=
SM.getImmediateMacroCallerLoc(
Loc);
11923 if(isa<CXXThisExpr>(
E)) {
11924 unsignedDiagID = IsCompare ? diag::warn_this_null_compare
11925: diag::warn_this_bool_conversion;
11930 boolIsAddressOf =
false;
11932 if(
auto*UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11933 if(UO->getOpcode() != UO_AddrOf)
11935IsAddressOf =
true;
11936 E= UO->getSubExpr();
11940 unsignedDiagID = IsCompare
11941? diag::warn_address_of_reference_null_compare
11942: diag::warn_address_of_reference_bool_conversion;
11950 autoComplainAboutNonnullParamOrCall = [&](
const Attr*NonnullAttr) {
11951 boolIsParam = isa<NonNullAttr>(NonnullAttr);
11953llvm::raw_string_ostream S(Str);
11955 unsignedDiagID = IsCompare ? diag::warn_nonnull_expr_compare
11956: diag::warn_cast_nonnull_to_bool;
11959 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11964 if(
auto*Callee =
Call->getDirectCallee()) {
11965 if(
const Attr*A = Callee->getAttr<ReturnsNonNullAttr>()) {
11966ComplainAboutNonnullParamOrCall(A);
11975 if(
const auto*MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11976 if(
const auto*MRecordDecl = MCallExpr->getRecordDecl();
11977MRecordDecl && MRecordDecl->isLambda()) {
11980<< MRecordDecl->getSourceRange() <<
Range<< IsEqual;
11990}
else if(
MemberExpr*M = dyn_cast<MemberExpr>(
E)) {
11991 D= M->getMemberDecl();
11995 if(!
D||
D->isWeak())
11999 if(
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
12002 if(
const Attr*A = PV->getAttr<NonNullAttr>()) {
12003ComplainAboutNonnullParamOrCall(A);
12007 if(
const auto*FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
12011 autoParamIter = llvm::find(FD->
parameters(), PV);
12012assert(ParamIter != FD->
param_end());
12013 unsignedParamNo = std::distance(FD->
param_begin(), ParamIter);
12016 if(!
NonNull->args_size()) {
12017ComplainAboutNonnullParamOrCall(
NonNull);
12022 if(ArgNo.getASTIndex() == ParamNo) {
12023ComplainAboutNonnullParamOrCall(
NonNull);
12037 if(IsAddressOf && IsFunction) {
12042 if(!IsAddressOf && !IsFunction && !IsArray)
12047llvm::raw_string_ostream S(Str);
12050 unsignedDiagID = IsCompare ? diag::warn_null_pointer_compare
12051: diag::warn_impcast_pointer_to_bool;
12058DiagType = AddressOf;
12059 else if(IsFunction)
12060DiagType = FunctionPointer;
12062DiagType = ArrayPointer;
12064llvm_unreachable(
"Could not determine diagnostic.");
12066<<
Range<< IsEqual;
12079 if(ReturnType.
isNull())
12117CheckArrayAccess(
E);
12124::CheckBoolLikeConversion(*
this,
E, CC);
12127voidSema::CheckForIntOverflow (
const Expr*
E) {
12132 const Expr*OriginalE = Exprs.pop_back_val();
12135 if(isa<BinaryOperator, UnaryOperator>(
E)) {
12140 if(
const auto*InitList = dyn_cast<InitListExpr>(OriginalE))
12141Exprs.append(InitList->inits().begin(), InitList->inits().end());
12142 else if(isa<ObjCBoxedExpr>(OriginalE))
12144 else if(
const auto*
Call= dyn_cast<CallExpr>(
E))
12145Exprs.append(
Call->arg_begin(),
Call->arg_end());
12146 else if(
const auto*Message = dyn_cast<ObjCMessageExpr>(
E))
12147Exprs.append(Message->arg_begin(), Message->arg_end());
12148 else if(
const auto*Construct = dyn_cast<CXXConstructExpr>(
E))
12149Exprs.append(Construct->arg_begin(), Construct->arg_end());
12150 else if(
const auto*Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12151Exprs.push_back(Temporary->getSubExpr());
12152 else if(
const auto*Array = dyn_cast<ArraySubscriptExpr>(
E))
12153Exprs.push_back(Array->getIdx());
12154 else if(
const auto*Compound = dyn_cast<CompoundLiteralExpr>(
E))
12155Exprs.push_back(Compound->getInitializer());
12156 else if(
const auto*New = dyn_cast<CXXNewExpr>(
E);
12157New && New->isArray()) {
12158 if(
autoArraySize = New->getArraySize())
12159Exprs.push_back(*ArraySize);
12160}
else if(
const auto*MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
12161Exprs.push_back(MTE->getSubExpr());
12162}
while(!Exprs.empty());
12177 classSequenceTree {
12181LLVM_PREFERRED_TYPE(
bool)
12182 unsignedMerged : 1;
12190 friend classSequenceTree;
12194 explicit Seq(
unsignedN) : Index(N) {}
12197 Seq() : Index(0) {}
12200SequenceTree() { Values.push_back(
Value(0)); }
12201 Seqroot()
const{
return Seq(0); }
12208 return Seq(Values.size() - 1);
12212 voidmerge(
SeqS) {
12213Values[S.Index].Merged =
true;
12219 boolisUnsequenced(
SeqCur,
SeqOld) {
12220 unsigned C= representative(Cur.Index);
12221 unsigned Target= representative(Old.Index);
12225 C= Values[
C].Parent;
12232 unsignedrepresentative(
unsignedK) {
12233 if(Values[K].Merged)
12235 returnValues[K].Parent = representative(Values[K].
Parent);
12255UK_ModAsSideEffect,
12257UK_Count = UK_ModAsSideEffect + 1
12263 const Expr*UsageExpr =
nullptr;
12264SequenceTree::Seq
Seq;
12266Usage() =
default;
12270Usage Uses[UK_Count];
12273 boolDiagnosed =
false;
12277 usingUsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12282SequenceTree
Tree;
12285UsageInfoMap UsageMap;
12288SequenceTree::Seq Region;
12303 structSequencedSubexpression {
12304SequencedSubexpression(SequenceChecker &Self)
12305: Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12306Self.ModAsSideEffect = &ModAsSideEffect;
12309~SequencedSubexpression() {
12310 for(
conststd::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12314UsageInfo &UI = Self.UsageMap[M.first];
12315 auto&SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12316Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12317SideEffectUsage = M.second;
12319Self.ModAsSideEffect = OldModAsSideEffect;
12322SequenceChecker &Self;
12331 classEvaluationTracker {
12333EvaluationTracker(SequenceChecker &Self)
12334: Self(Self), Prev(Self.EvalTracker) {
12335Self.EvalTracker =
this;
12338~EvaluationTracker() {
12339Self.EvalTracker = Prev;
12341Prev->EvalOK &= EvalOK;
12344 boolevaluate(
const Expr*
E,
bool&Result) {
12348Result, Self.SemaRef.Context,
12349Self.SemaRef.isConstantEvaluatedContext());
12354SequenceChecker &Self;
12355EvaluationTracker *Prev;
12356 boolEvalOK =
true;
12357} *EvalTracker =
nullptr;
12361 ObjectgetObject(
const Expr*
E,
boolMod)
const{
12364 if(Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12365 returngetObject(UO->getSubExpr(), Mod);
12366}
else if(
const BinaryOperator*BO = dyn_cast<BinaryOperator>(
E)) {
12367 if(BO->getOpcode() == BO_Comma)
12368 returngetObject(BO->getRHS(), Mod);
12369 if(Mod && BO->isAssignmentOp())
12370 returngetObject(BO->getLHS(), Mod);
12371}
else if(
const MemberExpr*ME = dyn_cast<MemberExpr>(
E)) {
12373 if(isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12374 returnME->getMemberDecl();
12375}
else if(
const DeclRefExpr*DRE = dyn_cast<DeclRefExpr>(
E))
12384 voidaddUsage(Object O, UsageInfo &UI,
const Expr*UsageExpr, UsageKind UK) {
12386Usage &
U= UI.Uses[UK];
12387 if(!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12391 if(UK == UK_ModAsSideEffect && ModAsSideEffect)
12392ModAsSideEffect->push_back(std::make_pair(O,
U));
12394 U.UsageExpr = UsageExpr;
12404 voidcheckUsage(Object O, UsageInfo &UI,
const Expr*UsageExpr,
12405UsageKind OtherKind,
boolIsModMod) {
12409 constUsage &
U= UI.Uses[OtherKind];
12410 if(!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12413 const Expr*Mod =
U.UsageExpr;
12414 const Expr*ModOrUse = UsageExpr;
12415 if(OtherKind == UK_Use)
12416std::swap(Mod, ModOrUse);
12420SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12421: diag::warn_unsequenced_mod_use)
12423UI.Diagnosed =
true;
12452 voidnotePreUse(Object O,
const Expr*UseExpr) {
12453UsageInfo &UI = UsageMap[O];
12455checkUsage(O, UI, UseExpr,
UK_ModAsValue,
false);
12458 voidnotePostUse(Object O,
const Expr*UseExpr) {
12459UsageInfo &UI = UsageMap[O];
12460checkUsage(O, UI, UseExpr,
UK_ModAsSideEffect,
12462addUsage(O, UI, UseExpr,
UK_Use);
12465 voidnotePreMod(Object O,
const Expr*ModExpr) {
12466UsageInfo &UI = UsageMap[O];
12468checkUsage(O, UI, ModExpr,
UK_ModAsValue,
true);
12469checkUsage(O, UI, ModExpr,
UK_Use,
false);
12472 voidnotePostMod(Object O,
const Expr*ModExpr, UsageKind UK) {
12473UsageInfo &UI = UsageMap[O];
12474checkUsage(O, UI, ModExpr,
UK_ModAsSideEffect,
12476addUsage(O, UI, ModExpr,
UK);
12480SequenceChecker(
Sema&S,
const Expr*
E,
12482:
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12486(void)this->WorkList;
12489 voidVisitStmt(
const Stmt*S) {
12493 voidVisitExpr(
const Expr*
E) {
12495Base::VisitStmt(
E);
12499 for(
auto*Sub : CSE->
children()) {
12500 const Expr*ChildExpr = dyn_cast_or_null<Expr>(Sub);
12515 voidVisitCastExpr(
const CastExpr*
E) {
12517 if(
E->getCastKind() == CK_LValueToRValue)
12518O = getObject(
E->getSubExpr(),
false);
12524notePostUse(O,
E);
12527 voidVisitSequencedExpressions(
const Expr*SequencedBefore,
12528 const Expr*SequencedAfter) {
12529SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12530SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12531SequenceTree::Seq OldRegion = Region;
12534SequencedSubexpression SeqBefore(*
this);
12535Region = BeforeRegion;
12536Visit(SequencedBefore);
12539Region = AfterRegion;
12540Visit(SequencedAfter);
12542Region = OldRegion;
12544 Tree.merge(BeforeRegion);
12545 Tree.merge(AfterRegion);
12553VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12560 voidVisitBinPtrMemD(
const BinaryOperator*BO) { VisitBinPtrMem(BO); }
12561 voidVisitBinPtrMemI(
const BinaryOperator*BO) { VisitBinPtrMem(BO); }
12567VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12574 voidVisitBinShl(
const BinaryOperator*BO) { VisitBinShlShr(BO); }
12575 voidVisitBinShr(
const BinaryOperator*BO) { VisitBinShlShr(BO); }
12580VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12592VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12596SequenceTree::Seq RHSRegion;
12597SequenceTree::Seq LHSRegion;
12599RHSRegion =
Tree.allocate(Region);
12600LHSRegion =
Tree.allocate(Region);
12602RHSRegion = Region;
12603LHSRegion = Region;
12605SequenceTree::Seq OldRegion = Region;
12621SequencedSubexpression SeqBefore(*
this);
12622Region = RHSRegion;
12626Region = LHSRegion;
12629 if(O && isa<CompoundAssignOperator>(BO))
12630notePostUse(O, BO);
12634Region = LHSRegion;
12637 if(O && isa<CompoundAssignOperator>(BO))
12638notePostUse(O, BO);
12640Region = RHSRegion;
12648Region = OldRegion;
12651SemaRef.
getLangOpts().CPlusPlus ? UK_ModAsValue
12652: UK_ModAsSideEffect);
12654 Tree.merge(RHSRegion);
12655 Tree.merge(LHSRegion);
12660VisitBinAssign(CAO);
12663 voidVisitUnaryPreInc(
const UnaryOperator*UO) { VisitUnaryPreIncDec(UO); }
12664 voidVisitUnaryPreDec(
const UnaryOperator*UO) { VisitUnaryPreIncDec(UO); }
12668 returnVisitExpr(UO);
12675SemaRef.
getLangOpts().CPlusPlus ? UK_ModAsValue
12676: UK_ModAsSideEffect);
12679 voidVisitUnaryPostInc(
const UnaryOperator*UO) { VisitUnaryPostIncDec(UO); }
12680 voidVisitUnaryPostDec(
const UnaryOperator*UO) { VisitUnaryPostIncDec(UO); }
12684 returnVisitExpr(UO);
12688notePostMod(O, UO, UK_ModAsSideEffect);
12697SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12698SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12699SequenceTree::Seq OldRegion = Region;
12701EvaluationTracker Eval(*
this);
12703SequencedSubexpression Sequenced(*
this);
12704Region = LHSRegion;
12711 boolEvalResult =
false;
12712 boolEvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12713 boolShouldVisitRHS = !EvalOK || !EvalResult;
12714 if(ShouldVisitRHS) {
12715Region = RHSRegion;
12719Region = OldRegion;
12720 Tree.merge(LHSRegion);
12721 Tree.merge(RHSRegion);
12730SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12731SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12732SequenceTree::Seq OldRegion = Region;
12734EvaluationTracker Eval(*
this);
12736SequencedSubexpression Sequenced(*
this);
12737Region = LHSRegion;
12743 boolEvalResult =
false;
12744 boolEvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12745 boolShouldVisitRHS = !EvalOK || EvalResult;
12746 if(ShouldVisitRHS) {
12747Region = RHSRegion;
12751Region = OldRegion;
12752 Tree.merge(LHSRegion);
12753 Tree.merge(RHSRegion);
12761SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12777SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12778SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12779SequenceTree::Seq OldRegion = Region;
12781EvaluationTracker Eval(*
this);
12783SequencedSubexpression Sequenced(*
this);
12784Region = ConditionRegion;
12794 boolEvalResult =
false;
12795 boolEvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12796 boolShouldVisitTrueExpr = !EvalOK || EvalResult;
12797 boolShouldVisitFalseExpr = !EvalOK || !EvalResult;
12798 if(ShouldVisitTrueExpr) {
12799Region = TrueRegion;
12802 if(ShouldVisitFalseExpr) {
12803Region = FalseRegion;
12807Region = OldRegion;
12808 Tree.merge(ConditionRegion);
12809 Tree.merge(TrueRegion);
12810 Tree.merge(FalseRegion);
12813 voidVisitCallExpr(
const CallExpr*CE) {
12825SequencedSubexpression Sequenced(*
this);
12830SequenceTree::Seq CalleeRegion;
12831SequenceTree::Seq OtherRegion;
12832if (SemaRef.getLangOpts().CPlusPlus17) {
12833CalleeRegion = Tree.allocate(Region);
12834OtherRegion = Tree.allocate(Region);
12836CalleeRegion = Region;
12837OtherRegion = Region;
12839SequenceTree::Seq OldRegion = Region;
12842Region = CalleeRegion;
12844SequencedSubexpression Sequenced(*this);
12845Visit(CE->getCallee());
12847Visit(CE->getCallee());
12851Region = OtherRegion;
12855Region = OldRegion;
12857Tree.merge(CalleeRegion);
12858Tree.merge(OtherRegion);
12876 returnVisitCallExpr(CXXOCE);
12887 caseOO_MinusEqual:
12889 caseOO_SlashEqual:
12890 caseOO_PercentEqual:
12891 caseOO_CaretEqual:
12894 caseOO_LessLessEqual:
12895 caseOO_GreaterGreaterEqual:
12896SequencingKind = RHSBeforeLHS;
12900 caseOO_GreaterGreater:
12906SequencingKind = LHSBeforeRHS;
12910SequencingKind = LHSBeforeRest;
12914SequencingKind = NoSequencing;
12918 if(SequencingKind == NoSequencing)
12919 returnVisitCallExpr(CXXOCE);
12922SequencedSubexpression Sequenced(*
this);
12925assert(SemaRef.getLangOpts().CPlusPlus17 &&
12926 "Should only get there with C++17 and above!");
12927assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12928 "Should only get there with an overloaded binary operator" 12929 " or an overloaded call operator!");
12931if (SequencingKind == LHSBeforeRest) {
12932assert(CXXOCE->getOperator() == OO_Call &&
12933 "We should only have an overloaded call operator here!");
12942SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12943SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12944SequenceTree::Seq OldRegion = Region;
12946assert(CXXOCE->getNumArgs() >= 1 &&
12947 "An overloaded call operator must have at least one argument" 12948 " for the postfix-expression!");
12949const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12950llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12951CXXOCE->getNumArgs() - 1);
12955Region = PostfixExprRegion;
12956SequencedSubexpression Sequenced(*this);
12957Visit(PostfixExpr);
12961Region = ArgsRegion;
12962for (const Expr *Arg : Args)
12965Region = OldRegion;
12966Tree.merge(PostfixExprRegion);
12967Tree.merge(ArgsRegion);
12969assert(CXXOCE->getNumArgs() == 2 &&
12970 "Should only have two arguments here!");
12971assert((SequencingKind == LHSBeforeRHS ||
12972SequencingKind == RHSBeforeLHS) &&
12973 "Unexpected sequencing kind!");
12977const Expr *E1 = CXXOCE->getArg(0);
12978const Expr *E2 = CXXOCE->getArg(1);
12979if (SequencingKind == RHSBeforeLHS)
12982return VisitSequencedExpressions(E1, E2);
12989SequencedSubexpression Sequenced(*
this);
12992 returnVisitExpr(CCE);
12995SequenceExpressionsInOrder(
13001 returnVisitExpr(ILE);
13004SequenceExpressionsInOrder(ILE->
inits());
13016SequenceTree::Seq
Parent= Region;
13017 for(
const Expr*
E: ExpressionList) {
13021Elts.push_back(Region);
13027 for(
unsignedI = 0; I < Elts.size(); ++I)
13028 Tree.merge(Elts[I]);
13032SequenceChecker::UsageInfo::UsageInfo() =
default;
13036voidSema::CheckUnsequencedOperations(
const Expr*
E) {
13038WorkList.push_back(
E);
13039 while(!WorkList.empty()) {
13040 const Expr*Item = WorkList.pop_back_val();
13041SequenceChecker(*
this, Item, WorkList);
13046 boolIsConstexpr) {
13048IsConstexpr || isa<ConstantExpr>(
E));
13049CheckImplicitConversions(
E, CheckLoc);
13051CheckUnsequencedOperations(
E);
13053CheckForIntOverflow(
E);
13067 if(
const auto*PointerTy = dyn_cast<PointerType>(PType)) {
13071 if(
const auto*ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13075 if(
const auto*ParenTy = dyn_cast<ParenType>(PType)) {
13089S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13093 boolCheckParameterNames) {
13094 boolHasInvalidParm =
false;
13096assert(Param &&
"null in a parameter list");
13105 if(!Param->isInvalidDecl() &&
13107diag::err_typecheck_decl_incomplete_type) ||
13109diag::err_abstract_type_in_decl,
13111Param->setInvalidDecl();
13112HasInvalidParm =
true;
13117 if(CheckParameterNames && Param->getIdentifier() ==
nullptr&&
13121 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13129 QualTypePType = Param->getOriginalType();
13137 if(!Param->isInvalidDecl()) {
13139 if(!ClassDecl->isInvalidDecl() &&
13140!ClassDecl->hasIrrelevantDestructor() &&
13141!ClassDecl->isDependentContext() &&
13142ClassDecl->isParamDestroyedInCallee()) {
13154 if(
const auto*
Attr= Param->getAttr<PassObjectSizeAttr>())
13155 if(!Param->getType().isConstQualified())
13156 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13160 if(
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13165 if(
auto*RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13166CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13171 if(!Param->isInvalidDecl() &&
13173Param->setInvalidDecl();
13174HasInvalidParm =
true;
13175 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13179 returnHasInvalidParm;
13182std::optional<std::pair<
13191staticstd::pair<CharUnits, CharUnits>
13199 if(
Base->isVirtual()) {
13206BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
13213DerivedType =
Base->getType();
13216 returnstd::make_pair(BaseAlignment, Offset);
13220staticstd::optional<std::pair<CharUnits, CharUnits>>
13226 returnstd::nullopt;
13231 returnstd::nullopt;
13235 CharUnitsOffset = EltSize * IdxRes->getExtValue();
13238 returnstd::make_pair(
P->first,
P->second + Offset);
13244 returnstd::make_pair(
13245 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13251std::optional<std::pair<
13259 caseStmt::CStyleCastExprClass:
13260 caseStmt::CXXStaticCastExprClass:
13261 caseStmt::ImplicitCastExprClass: {
13262 auto*CE = cast<CastExpr>(
E);
13263 const Expr*From = CE->getSubExpr();
13264 switch(CE->getCastKind()) {
13269 caseCK_UncheckedDerivedToBase:
13270 caseCK_DerivedToBase: {
13280 caseStmt::ArraySubscriptExprClass: {
13281 auto*ASE = cast<ArraySubscriptExpr>(
E);
13285 caseStmt::DeclRefExprClass: {
13286 if(
auto*VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13289 if(!VD->getType()->isReferenceType()) {
13291 if(VD->hasDependentAlignment())
13300 caseStmt::MemberExprClass: {
13301 auto*ME = cast<MemberExpr>(
E);
13302 auto*FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13306std::optional<std::pair<CharUnits, CharUnits>>
P;
13315 returnstd::make_pair(
P->first,
13318 caseStmt::UnaryOperatorClass: {
13319 auto*UO = cast<UnaryOperator>(
E);
13328 caseStmt::BinaryOperatorClass: {
13329 auto*BO = cast<BinaryOperator>(
E);
13340 returnstd::nullopt;
13345std::optional<std::pair<
13354 caseStmt::CStyleCastExprClass:
13355 caseStmt::CXXStaticCastExprClass:
13356 caseStmt::ImplicitCastExprClass: {
13357 auto*CE = cast<CastExpr>(
E);
13358 const Expr*From = CE->getSubExpr();
13359 switch(CE->getCastKind()) {
13364 caseCK_ArrayToPointerDecay:
13366 caseCK_UncheckedDerivedToBase:
13367 caseCK_DerivedToBase: {
13377 caseStmt::CXXThisExprClass: {
13382 caseStmt::UnaryOperatorClass: {
13383 auto*UO = cast<UnaryOperator>(
E);
13388 caseStmt::BinaryOperatorClass: {
13389 auto*BO = cast<BinaryOperator>(
E);
13397 if(Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13398std::swap(LHS, RHS);
13408 returnstd::nullopt;
13413std::optional<std::pair<CharUnits, CharUnits>>
P=
13417 return P->first.alignmentAtOffset(
P->second);
13435 if(!DestPtr)
return;
13441 if(DestAlign.
isOne())
return;
13445 if(!SrcPtr)
return;
13456 if(SrcAlign >= DestAlign)
return;
13460<<
static_cast<unsigned>(SrcAlign.
getQuantity())
13461<<
static_cast<unsigned>(DestAlign.
getQuantity())
13465voidSema::CheckArrayAccess(
const Expr*BaseExpr,
const Expr*IndexExpr,
13467 boolAllowOnePastEnd,
boolIndexNegated) {
13476 const Type*EffectiveType =
13483StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13485 const Type*BaseType =
13487 boolIsUnboundedArray =
13489 Context, StrictFlexArraysLevel,
13499llvm::APSInt index =
Result.Val.getInt();
13500 if(IndexNegated) {
13501index.setIsUnsigned(
false);
13505 if(IsUnboundedArray) {
13508 if(index.isUnsigned() || !index.isNegative()) {
13510 unsignedAddrBits = ASTC.getTargetInfo().getPointerWidth(
13512 if(index.getBitWidth() < AddrBits)
13513index = index.zext(AddrBits);
13514std::optional<CharUnits> ElemCharUnits =
13515ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13518 if(!ElemCharUnits || ElemCharUnits->isZero())
13520llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13525 if(index.getActiveBits() <= AddrBits) {
13527llvm::APInt Product(index);
13529Product = Product.umul_ov(ElemBytes, Overflow);
13530 if(!Overflow && Product.getActiveBits() <= AddrBits)
13536llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13537MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13539ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13540MaxElems = MaxElems.udiv(ElemBytes);
13543ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13544: diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13550<<
toString(index, 10,
true) << AddrBits
13551<< (
unsigned)ASTC.toBits(*ElemCharUnits)
13552<<
toString(ElemBytes, 10,
false)
13553<<
toString(MaxElems, 10,
false)
13554<< (
unsigned)MaxElems.getLimitedValue(~0
U)
13559 while(
const auto*ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13561 if(
const auto*DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13563 if(
const auto*ME = dyn_cast<MemberExpr>(BaseExpr))
13564ND = ME->getMemberDecl();
13568 PDiag(diag::note_array_declared_here) << ND);
13573 if(index.isUnsigned() || !index.isNegative()) {
13583llvm::APInt size = ArrayTy->
getSize();
13585 if(BaseType != EffectiveType) {
13593 if(!ptrarith_typesize)
13596 if(ptrarith_typesize != array_typesize) {
13598 uint64_tratio = array_typesize / ptrarith_typesize;
13602 if(ptrarith_typesize * ratio == array_typesize)
13603size *= llvm::APInt(size.getBitWidth(), ratio);
13607 if(size.getBitWidth() > index.getBitWidth())
13608index = index.zext(size.getBitWidth());
13609 else if(size.getBitWidth() < index.getBitWidth())
13610size = size.zext(index.getBitWidth());
13616 if(AllowOnePastEnd ? index.ule(size) : index.ult(size))
13633 unsignedDiagID = ASE ? diag::warn_array_index_exceeds_bounds
13634: diag::warn_ptr_arith_exceeds_bounds;
13635 unsignedCastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13643 unsignedDiagID = diag::warn_array_index_precedes_bounds;
13645DiagID = diag::warn_ptr_arith_precedes_bounds;
13646 if(index.isNegative()) index = -index;
13656 while(
const auto*ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13658 if(
const auto*DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13660 if(
const auto*ME = dyn_cast<MemberExpr>(BaseExpr))
13661ND = ME->getMemberDecl();
13665 PDiag(diag::note_array_declared_here) << ND);
13668voidSema::CheckArrayAccess(
const Expr*
expr) {
13669 intAllowOnePastEnd = 0;
13671 expr=
expr->IgnoreParenImpCasts();
13672 switch(
expr->getStmtClass()) {
13673 caseStmt::ArraySubscriptExprClass: {
13676AllowOnePastEnd > 0);
13680 caseStmt::MemberExprClass: {
13681 expr= cast<MemberExpr>(
expr)->getBase();
13684 caseStmt::ArraySectionExprClass: {
13690 nullptr, AllowOnePastEnd > 0);
13693 caseStmt::UnaryOperatorClass: {
13709 caseStmt::ConditionalOperatorClass: {
13712CheckArrayAccess(lhs);
13714CheckArrayAccess(rhs);
13717 caseStmt::CXXOperatorCallExprClass: {
13718 const auto*OCE = cast<CXXOperatorCallExpr>(
expr);
13719 for(
const auto*Arg : OCE->arguments())
13720CheckArrayAccess(Arg);
13730 Expr*RHS,
boolisProperty) {
13742S.
Diag(
Loc, diag::warn_arc_literal_assign)
13744<< (isProperty ? 0 : 1)
13752 Expr*RHS,
boolisProperty) {
13755 if(
cast->getCastKind() == CK_ARCConsumeObject) {
13756S.
Diag(
Loc, diag::warn_arc_retained_assign)
13758<< (isProperty ? 0 : 1)
13762RHS =
cast->getSubExpr();
13791= dyn_cast<ObjCPropertyRefExpr>(LHS->
IgnoreParens());
13833 if(
cast->getCastKind() == CK_ARCConsumeObject) {
13834 Diag(
Loc, diag::warn_arc_retained_property_assign)
13838RHS =
cast->getSubExpr();
13861 boolStmtLineInvalid;
13864 if(StmtLineInvalid)
13867 boolBodyLineInvalid;
13870 if(BodyLineInvalid)
13874 if(StmtLine != BodyLine)
13889 const NullStmt*NBody = dyn_cast<NullStmt>(Body);
13898 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13902 const Stmt*PossibleBody) {
13908 if(
const ForStmt*FS = dyn_cast<ForStmt>(S)) {
13909StmtLoc = FS->getRParenLoc();
13910Body = FS->getBody();
13911DiagID = diag::warn_empty_for_body;
13912}
else if(
const WhileStmt*WS = dyn_cast<WhileStmt>(S)) {
13913StmtLoc = WS->getRParenLoc();
13914Body = WS->getBody();
13915DiagID = diag::warn_empty_while_body;
13920 const NullStmt*NBody = dyn_cast<NullStmt>(Body);
13943 boolProbableTypo = isa<CompoundStmt>(PossibleBody);
13944 if(!ProbableTypo) {
13945 boolBodyColInvalid;
13948 if(BodyColInvalid)
13951 boolStmtColInvalid;
13954 if(StmtColInvalid)
13957 if(BodyCol > StmtCol)
13958ProbableTypo =
true;
13961 if(ProbableTypo) {
13963 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13971 if(
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13983 if(
const auto*CE = dyn_cast<CallExpr>(RHSExpr);
13985RHSExpr = CE->
getArg(0);
13986 else if(
const auto*CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13987CXXSCE && CXXSCE->isXValue())
13988RHSExpr = CXXSCE->getSubExpr();
13992 const DeclRefExpr*LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13993 const DeclRefExpr*RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13996 if(LHSDeclRef && RHSDeclRef) {
14003 auto D=
Diag(OpLoc, diag::warn_self_move)
14019 const Expr*LHSBase = LHSExpr;
14020 const Expr*RHSBase = RHSExpr;
14021 const MemberExpr*LHSME = dyn_cast<MemberExpr>(LHSExpr);
14022 const MemberExpr*RHSME = dyn_cast<MemberExpr>(RHSExpr);
14023 if(!LHSME || !RHSME)
14026 while(LHSME && RHSME) {
14031LHSBase = LHSME->
getBase();
14032RHSBase = RHSME->
getBase();
14033LHSME = dyn_cast<MemberExpr>(LHSBase);
14034RHSME = dyn_cast<MemberExpr>(RHSBase);
14037LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
14038RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
14039 if(LHSDeclRef && RHSDeclRef) {
14046 Diag(OpLoc, diag::warn_self_move)
14052 if(isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
14053 Diag(OpLoc, diag::warn_self_move)
14077 boolAreUnionMembers =
false) {
14078[[maybe_unused]]
const Type*Field1Parent =
14080[[maybe_unused]]
const Type*Field2Parent =
14085 "Can't evaluate layout compatibility between a struct field and a " 14088(AreUnionMembers && Field1Parent->
isUnionType())) &&
14089 "AreUnionMembers should be 'true' for union fields (only).");
14102 if(Bits1 != Bits2)
14106 if(Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14107Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14110 if(!AreUnionMembers &&
14122 if(
const CXXRecordDecl*D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14123RD1 = D1CXX->getStandardLayoutBaseWithFields();
14125 if(
const CXXRecordDecl*D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14126RD2 = D2CXX->getStandardLayoutBaseWithFields();
14131return isLayoutCompatible(C, F1, F2);
14140 for(
auto*Field2 : RD2->
fields())
14141UnmatchedFields.insert(Field2);
14143 for(
auto*Field1 : RD1->
fields()) {
14144 autoI = UnmatchedFields.begin();
14145 auto E= UnmatchedFields.end();
14147 for( ; I !=
E; ++I) {
14149 bool Result= UnmatchedFields.erase(*I);
14159 returnUnmatchedFields.empty();
14185 if(
C.hasSameType(T1, T2))
14194 if(TC1 == Type::Enum) {
14196cast<EnumType>(T1)->getDecl(),
14197cast<EnumType>(T2)->getDecl());
14198}
else if(TC1 == Type::Record) {
14203cast<RecordType>(T1)->getDecl(),
14204cast<RecordType>(T2)->getDecl());
14218 QualTypeBaseT =
Base->getType()->getCanonicalTypeUnqualified();
14249 const ValueDecl**VD, uint64_t *MagicValue,
14250 boolisConstantEvaluated) {
14258 caseStmt::UnaryOperatorClass: {
14267 caseStmt::DeclRefExprClass: {
14268 const DeclRefExpr*DRE = cast<DeclRefExpr>(TypeExpr);
14273 caseStmt::IntegerLiteralClass: {
14275llvm::APInt MagicValueAPInt = IL->
getValue();
14276 if(MagicValueAPInt.getActiveBits() <= 64) {
14277*MagicValue = MagicValueAPInt.getZExtValue();
14283 caseStmt::BinaryConditionalOperatorClass:
14284 caseStmt::ConditionalOperatorClass: {
14286cast<AbstractConditionalOperator>(TypeExpr);
14289isConstantEvaluated)) {
14299 caseStmt::BinaryOperatorClass: {
14302TypeExpr = BO->
getRHS();
14332 constllvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14335 boolisConstantEvaluated) {
14336FoundWrongKind =
false;
14341uint64_t MagicValue;
14343 if(!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14347 if(TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14348 if(I->getArgumentKind() != ArgumentKind) {
14349FoundWrongKind =
true;
14352 TypeInfo.Type = I->getMatchingCType();
14353 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14354 TypeInfo.MustBeNull = I->getMustBeNull();
14365MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14366 if(I == MagicValues->end())
14375 boolLayoutCompatible,
14377 if(!TypeTagForDatatypeMagicValues)
14378TypeTagForDatatypeMagicValues.reset(
14379 newllvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14382(*TypeTagForDatatypeMagicValues)[Magic] =
14398 return(T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14399(T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14400(T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14401(T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14404voidSema::CheckArgumentWithTypeTag(
constArgumentWithTypeTagAttr *
Attr,
14408 boolIsPointerAttr =
Attr->getIsPointer();
14411 unsignedTypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14412 if(TypeTagIdxAST >= ExprArgs.size()) {
14413 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14414<< 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14417 const Expr*TypeTagExpr = ExprArgs[TypeTagIdxAST];
14418 boolFoundWrongKind;
14421TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14423 if(FoundWrongKind)
14425diag::warn_type_tag_for_datatype_wrong_kind)
14431 unsignedArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14432 if(ArgumentIdxAST >= ExprArgs.size()) {
14433 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14434<< 1 <<
Attr->getArgumentIdx().getSourceIndex();
14437 const Expr*ArgumentExpr = ExprArgs[ArgumentIdxAST];
14438 if(IsPointerAttr) {
14440 if(
const ImplicitCastExpr*ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14441 if(ICE->getType()->isVoidPointerType() &&
14442ICE->getCastKind() == CK_BitCast)
14443ArgumentExpr = ICE->getSubExpr();
14456diag::warn_type_safety_null_pointer_required)
14468 boolmismatch =
false;
14469 if(!
TypeInfo.LayoutCompatible) {
14480(!IsPointerAttr &&
IsSameCharType(ArgumentType, RequiredType)))
14491 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14492<< ArgumentType << ArgumentKind
14493<<
TypeInfo.LayoutCompatible << RequiredType
14500MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14504 for(MisalignedMember &m : MisalignedMembers) {
14506 if(ND->
getName().empty()) {
14510 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14513MisalignedMembers.clear();
14520 if(isa<UnaryOperator>(
E) &&
14521cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14522 auto*Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14523 if(isa<MemberExpr>(Op)) {
14524 auto*MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14525 if(MA != MisalignedMembers.end() &&
14530MisalignedMembers.erase(MA);
14539 const auto*ME = dyn_cast<MemberExpr>(
E);
14551 boolAnyIsPacked =
false;
14553 QualTypeBaseType = ME->getBase()->getType();
14563 auto*FD = dyn_cast<FieldDecl>(MD);
14569AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14570ReverseMemberChain.push_back(FD);
14573ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14575assert(TopME &&
"We did not compute a topmost MemberExpr!");
14582 const auto*DRE = dyn_cast<DeclRefExpr>(TopBase);
14586 if(!DRE && !isa<CXXThisExpr>(TopBase))
14593 if(ExpectedAlignment.
isOne())
14598 for(
const FieldDecl*FD : llvm::reverse(ReverseMemberChain))
14603ReverseMemberChain.back()->getParent()->getTypeForDecl());
14607 if(DRE && !TopME->
isArrow()) {
14610CompleteObjectAlignment =
14615 if(Offset % ExpectedAlignment != 0 ||
14618CompleteObjectAlignment < ExpectedAlignment) {
14629 for(
FieldDecl*FDI : ReverseMemberChain) {
14630 if(FDI->hasAttr<PackedAttr>() ||
14631FDI->getParent()->hasAttr<PackedAttr>()) {
14633Alignment = std::min(
14639assert(FD &&
"We did not find a packed FieldDecl!");
14640Action(
E, FD->
getParent(), FD, Alignment);
14644voidSema::CheckAddressOfPackedMember(
Expr*rhs) {
14645 using namespacestd::placeholders;
14648rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14682boolSema::BuiltinElementwiseMath(
CallExpr*TheCall,
boolFPOnly) {
14695 if(
auto*VecTy0 = (*Res)->getAs<
VectorType>())
14696TheCall->
setType(VecTy0->getElementType());
14709 returnS.
Diag(
Loc, diag::err_conv_mixed_enum_types_cxx26)
14719 returnstd::nullopt;
14723 returnstd::nullopt;
14726 for(
intI = 0; I < 2; ++I) {
14730 returnstd::nullopt;
14731Args[I] = Converted.
get();
14739 Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
14740 returnstd::nullopt;
14745 returnstd::nullopt;
14748 returnstd::nullopt;
14751TheCall->
setArg(0, Args[0]);
14752TheCall->
setArg(1, Args[1]);
14757 boolCheckForFloatArgs) {
14769 for(
intI = 0; I < 3; ++I) {
14774Args[I] = Converted.
get();
14777 if(CheckForFloatArgs) {
14778 intArgOrdinal = 1;
14779 for(
Expr*Arg : Args) {
14781Arg->
getType(), ArgOrdinal++))
14785 intArgOrdinal = 1;
14786 for(
Expr*Arg : Args) {
14793 for(
intI = 1; I < 3; ++I) {
14794 if(Args[0]->getType().getCanonicalType() !=
14795Args[I]->getType().getCanonicalType()) {
14796 return Diag(Args[0]->getBeginLoc(),
14797diag::err_typecheck_call_different_arg_types)
14801TheCall->
setArg(I, Args[I]);
14804TheCall->
setType(Args[0]->getType());
14808boolSema::PrepareBuiltinReduceMathOneArgCall(
CallExpr*TheCall) {
14820boolSema::BuiltinNonDeterministicValue(
CallExpr*TheCall) {
14829<< 1 <<
0 << TyArg;
14843 Expr*Matrix = MatrixArg.
get();
14848<< 1 <<
1 << Matrix->
getType();
14855MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14858TheCall->
setType(ResultType);
14861TheCall->
setArg(0, Matrix);
14866staticstd::optional<unsigned>
14869std::optional<llvm::APSInt>
Value=
14876uint64_t
Dim=
Value->getZExtValue();
14895 unsignedPtrArgIdx = 0;
14896 Expr*PtrExpr = TheCall->
getArg(PtrArgIdx);
14901 boolArgError =
false;
14908PtrExpr = PtrConv.
get();
14909TheCall->
setArg(0, PtrExpr);
14920<< PtrArgIdx + 1 <<
2 << PtrExpr->
getType();
14927<< PtrArgIdx + 1 <<
2
14934 autoApplyArgumentConversions = [
this](
Expr*
E) {
14943 ExprResultRowsConv = ApplyArgumentConversions(RowsExpr);
14945RowsExpr = RowsConv.
get();
14946TheCall->
setArg(1, RowsExpr);
14948RowsExpr =
nullptr;
14950 ExprResultColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14952ColumnsExpr = ColumnsConv.
get();
14953TheCall->
setArg(2, ColumnsExpr);
14955ColumnsExpr =
nullptr;
14966std::optional<unsigned> MaybeRows;
14970std::optional<unsigned> MaybeColumns;
14975 ExprResultStrideConv = ApplyArgumentConversions(StrideExpr);
14978StrideExpr = StrideConv.
get();
14979TheCall->
setArg(3, StrideExpr);
14982 if(std::optional<llvm::APSInt>
Value=
14985 if(Stride < *MaybeRows) {
14987diag::err_builtin_matrix_stride_too_small);
14993 if(ArgError || !MaybeRows || !MaybeColumns)
15006 unsignedPtrArgIdx = 1;
15008 Expr*PtrExpr = TheCall->
getArg(PtrArgIdx);
15011 boolArgError =
false;
15017MatrixExpr = MatrixConv.
get();
15018TheCall->
setArg(0, MatrixExpr);
15027 Diag(MatrixExpr->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
15028<< 1 <<
1 << MatrixExpr->
getType();
15036PtrExpr = PtrConv.
get();
15037TheCall->
setArg(1, PtrExpr);
15048<< PtrArgIdx + 1 <<
2 << PtrExpr->
getType();
15053 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
15060diag::err_builtin_matrix_pointer_arg_mismatch)
15061<< ElementTy << MatrixTy->getElementType();
15076StrideExpr = StrideConv.
get();
15077TheCall->
setArg(2, StrideExpr);
15082 if(std::optional<llvm::APSInt>
Value=
15085 if(Stride < MatrixTy->getNumRows()) {
15087diag::err_builtin_matrix_stride_too_small);
15107 if(!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15112llvm::StringSet<> CalleeTCBs;
15113 for(
const auto*A : Callee->specific_attrs<EnforceTCBAttr>())
15114CalleeTCBs.insert(A->getTCBName());
15115 for(
const auto*A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15116CalleeTCBs.insert(A->getTCBName());
15120 for(
const auto*A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15121StringRef CallerTCB = A->getTCBName();
15122 if(CalleeTCBs.count(CallerTCB) == 0) {
15123this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15124<< Callee << CallerTCB;
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth)
static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool)
static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool pruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, SourceLocation CC)
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool isKnownToHaveUnsignedValue(Expr *E)
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static bool requiresParensToAddCast(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool IsEnumConstOrFromMacro(Sema &S, Expr *E)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static bool HasEnumType(Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
const NestedNameSpecifier * Specifier
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an RISC-V vector builtin type and a VectorType that is a fixed-len...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible RISC-V vector types as defined by -flax-vect...
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
const TargetInfo * getAuxTargetInfo() const
llvm::APFixedPoint getFixedPointMin(QualType Ty) const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getExceptionObjectType(QualType T) const
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
CanQualType UnsignedShortTy
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
llvm::APFixedPoint getFixedPointMax(QualType Ty) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
CanQualType getNSIntegerType() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
CanQualType getNSUIntegerType() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
std::unique_ptr< AtomicScopeModel > getScopeModel() const
Get atomic scope model.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ConceptDecl * getTypeConstraintConcept() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getExprLoc() const
bool isEqualityOp() const
static bool isAdditiveOp(Opcode Opc)
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
llvm::StringRef getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
bool isTSBuiltin(unsigned ID) const
Return true if this function is a target-specific builtin.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
void setExprNeedsCleanups(bool SideEffects)
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
Declaration of a C++20 concept.
ConditionalOperator - The ?: ternary operator.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a concrete matrix type with constant number of rows and columns.
static constexpr unsigned getMaxElementsPerDimension()
Returns the maximum number of elements per dimension.
static constexpr bool isDimensionValid(size_t NumElements)
Returns true if NumElements is a valid matrix dimension.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Expr * getOperand() const
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
DynamicCountPointerKind getKind() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isComplete() const
Returns true if this can be considered a complete type.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
unsigned getNumPositiveBits() const
Returns the width in bits required to store all the non-negative enumerators of this enum.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
const FieldDecl * findCountedByField() const
Find the FieldDecl specified in a FAM's "counted_by" attribute.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
bool isSignedCharBool(QualType Ty)
void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)
Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
static FormatStringType GetFormatStringType(const FormatAttr *Format)
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall)
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
@ ACK_Comparison
A comparison.
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs=true)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
bool isConstantEvaluatedContext() const
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, bool FPOnly=false)
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
Exposes information about the current target.
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const
Determine whether the given pointer-authentication key is valid.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
virtual bool supportsCpuInit() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const llvm::fltSemantics & getLongDoubleFormat() const
virtual bool checkArithmeticFenceSupported() const
Controls if __arithmetic_fence is supported in the targeted backend.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
virtual bool hasSjLjLowering() const
Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
const Type * getTypeForDecl() const
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isBooleanType() const
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isFloat16Type() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
The iterator over UnresolvedSets.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
WhileStmt - This represents a 'while' stmt.
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
std::optional< ConversionSpecifier > getStandardSpecifier() const
unsigned getLength() const
const char * getStart() const
const char * toString() const
ArgType getArgType(ASTContext &Ctx) const
const char * getStart() const
unsigned getArgIndex() const
bool hasDataArgument() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
Class representing optional flags with location and representation information.
const char * toString() const
const char * getPosition() const
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
bool parseFormatStringHasFormattingSpecifiers(const char *Begin, const char *End, const LangOptions &LO, const TargetInfo &Target)
Return true if the given string has at least one formatting specifier.
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
ComparisonResult
Indicates the result of a tentative comparison.
uint32_t Literal
Literals are represented as positive integers.
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
ActionResult< ParsedType > TypeResult
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
const FunctionProtoType * T
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
FormatArgumentPassingKind ArgPassingKind
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4