81#include "llvm/ADT/APFloat.h"
82#include "llvm/ADT/APInt.h"
83#include "llvm/ADT/APSInt.h"
84#include "llvm/ADT/ArrayRef.h"
85#include "llvm/ADT/DenseMap.h"
86#include "llvm/ADT/FoldingSet.h"
87#include "llvm/ADT/STLExtras.h"
88#include "llvm/ADT/STLForwardCompat.h"
89#include "llvm/ADT/SmallBitVector.h"
90#include "llvm/ADT/SmallPtrSet.h"
91#include "llvm/ADT/SmallString.h"
92#include "llvm/ADT/SmallVector.h"
93#include "llvm/ADT/StringExtras.h"
94#include "llvm/ADT/StringRef.h"
95#include "llvm/ADT/StringSet.h"
96#include "llvm/ADT/StringSwitch.h"
97#include "llvm/Support/AtomicOrdering.h"
98#include "llvm/Support/Compiler.h"
99#include "llvm/Support/ConvertUTF.h"
100#include "llvm/Support/ErrorHandling.h"
101#include "llvm/Support/Format.h"
102#include "llvm/Support/Locale.h"
103#include "llvm/Support/MathExtras.h"
104#include "llvm/Support/SaveAndRestore.h"
105#include "llvm/Support/raw_ostream.h"
106#include "llvm/TargetParser/RISCVTargetParser.h"
107#include "llvm/TargetParser/Triple.h"
120using namespace clang;
124 unsigned ByteNo)
const {
135 unsigned ArgCount =
Call->getNumArgs();
136 if (ArgCount >= MinArgCount)
139 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
140 << 0 << MinArgCount << ArgCount
141 << 0 <<
Call->getSourceRange();
145 unsigned ArgCount =
Call->getNumArgs();
146 if (ArgCount <= MaxArgCount)
148 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
149 << 0 << MaxArgCount << ArgCount
150 << 0 <<
Call->getSourceRange();
154 unsigned MaxArgCount) {
160 unsigned ArgCount =
Call->getNumArgs();
161 if (ArgCount == DesiredArgCount)
166 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
170 Call->getArg(ArgCount - 1)->getEndLoc());
172 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
173 << 0 << DesiredArgCount << ArgCount
178 bool HasError =
false;
180 for (
const Expr *Arg :
Call->arguments()) {
181 if (Arg->isValueDependent())
184 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
185 int DiagMsgKind = -1;
187 if (!ArgString.has_value())
189 else if (ArgString->find(
'$') != std::string::npos)
192 if (DiagMsgKind >= 0) {
193 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
194 << DiagMsgKind << Arg->getSourceRange();
203 if (
Value->isTypeDependent())
210 if (Result.isInvalid())
212 Value = Result.get();
234 if (!Literal || !Literal->isOrdinary()) {
247 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
255 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
256 if (!Literal || !Literal->isWide()) {
257 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
258 << Arg->getSourceRange();
295 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
326 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
328 auto IsValidIntegerType = [](
QualType Ty) {
329 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
336 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
340 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
346 if (!IsValidIntegerType(AlignOp->
getType())) {
357 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
358 llvm::APSInt MaxValue(
359 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
360 if (AlignValue < 1) {
361 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
364 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
369 if (!AlignValue.isPowerOf2()) {
370 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
373 if (AlignValue == 1) {
374 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
375 << IsBooleanAlignBuiltin;
403 std::pair<unsigned, const char *> Builtins[] = {
404 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
405 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
406 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
409 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
416 auto ValidCkdIntType = [](
QualType QT) {
419 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
420 return (BT->getKind() >= BuiltinType::Short &&
421 BT->getKind() <= BuiltinType::Int128) || (
422 BT->getKind() >= BuiltinType::UShort &&
423 BT->getKind() <= BuiltinType::UInt128) ||
424 BT->getKind() == BuiltinType::UChar ||
425 BT->getKind() == BuiltinType::SChar;
430 for (
unsigned I = 0; I < 2; ++I) {
436 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
455 !PtrTy->getPointeeType()->isIntegerType() ||
456 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
457 PtrTy->getPointeeType().isConstQualified()) {
459 diag::err_overflow_builtin_must_be_ptr_int)
467 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
468 for (
unsigned I = 0; I < 3; ++I) {
469 const auto Arg = TheCall->
getArg(I);
472 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
474 return S.
Diag(Arg->getBeginLoc(),
475 diag::err_overflow_builtin_bit_int_max_size)
484struct BuiltinDumpStructGenerator {
488 SmallVector<Expr *, 32> Actions;
489 DiagnosticErrorTrap ErrorTracker;
490 PrintingPolicy Policy;
492 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
493 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
494 Policy(S.Context.getPrintingPolicy()) {
498 Expr *makeOpaqueValueExpr(Expr *Inner) {
502 Actions.push_back(OVE);
506 Expr *getStringLiteral(llvm::StringRef Str) {
509 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
512 bool callPrintFunction(llvm::StringRef Format,
513 llvm::ArrayRef<Expr *> Exprs = {}) {
514 SmallVector<Expr *, 8> Args;
516 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
518 Args.push_back(getStringLiteral(Format));
519 llvm::append_range(Args, Exprs);
522 Sema::CodeSynthesisContext Ctx;
535 Actions.push_back(RealCall.
get());
541 Expr *getIndentString(
unsigned Depth) {
545 llvm::SmallString<32>
Indent;
547 return getStringLiteral(
Indent);
551 return getStringLiteral(
T.getAsString(Policy));
554 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
555 llvm::raw_svector_ostream
OS(Str);
559 if (
auto *BT =
T->
getAs<BuiltinType>()) {
560 switch (BT->getKind()) {
561 case BuiltinType::Bool:
564 case BuiltinType::Char_U:
565 case BuiltinType::UChar:
568 case BuiltinType::Char_S:
569 case BuiltinType::SChar:
577 analyze_printf::PrintfSpecifier
Specifier;
580 if (
Specifier.getConversionSpecifier().getKind() ==
581 analyze_printf::PrintfConversionSpecifier::sArg) {
587 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
607 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
608 Expr *IndentLit = getIndentString(Depth);
610 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
611 : callPrintFunction(
"%s", {TypeLit}))
614 return dumpRecordValue(RD, E, IndentLit, Depth);
618 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
627 Expr *RecordArg = makeOpaqueValueExpr(E);
630 if (callPrintFunction(
" {\n"))
634 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
635 for (
const auto &Base : CXXRD->bases()) {
643 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
649 Expr *FieldIndentArg = getIndentString(Depth + 1);
652 for (
auto *D : RD->
decls()) {
653 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
654 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
655 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
658 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
659 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
661 getStringLiteral(FD->getName())};
663 if (FD->isBitField()) {
667 FD->getBitWidthValue());
675 CXXScopeSpec(), Loc, IFD,
678 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
680 DeclarationNameInfo(FD->getDeclName(), Loc));
681 if (
Field.isInvalid())
684 auto *InnerRD = FD->getType()->getAsRecordDecl();
685 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
686 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
688 if (callPrintFunction(Format, Args) ||
689 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
693 if (appendFormatSpecifier(FD->getType(), Format)) {
695 Args.push_back(
Field.get());
705 Args.push_back(FieldAddr.
get());
708 if (callPrintFunction(Format, Args))
713 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
714 : callPrintFunction(
"}\n");
717 Expr *buildWrapper() {
720 TheCall->
setType(Wrapper->getType());
741 diag::err_expected_struct_pointer_argument)
750 diag::err_incomplete_type))
759 switch (BT ? BT->getKind() : BuiltinType::Void) {
760 case BuiltinType::Dependent:
761 case BuiltinType::Overload:
762 case BuiltinType::BoundMember:
763 case BuiltinType::PseudoObject:
764 case BuiltinType::UnknownAny:
765 case BuiltinType::BuiltinFn:
771 diag::err_expected_callable_argument)
777 BuiltinDumpStructGenerator Generator(S, TheCall);
783 Expr *PtrArg = PtrArgResult.
get();
787 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
790 return Generator.buildWrapper();
802 if (
Call->getStmtClass() != Stmt::CallExprClass) {
803 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
804 <<
Call->getSourceRange();
809 if (CE->getCallee()->getType()->isBlockPointerType()) {
810 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
811 <<
Call->getSourceRange();
815 const Decl *TargetDecl = CE->getCalleeDecl();
816 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
817 if (FD->getBuiltinID()) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
819 <<
Call->getSourceRange();
824 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
825 <<
Call->getSourceRange();
833 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
847 BuiltinCall->
setType(CE->getType());
851 BuiltinCall->
setArg(1, ChainResult.
get());
858class ScanfDiagnosticFormatHandler
862 using ComputeSizeFunction =
863 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
867 using DiagnoseFunction =
868 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
870 ComputeSizeFunction ComputeSizeArgument;
871 DiagnoseFunction Diagnose;
874 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
875 DiagnoseFunction Diagnose)
876 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
878 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
879 const char *StartSpecifier,
880 unsigned specifierLen)
override {
884 unsigned NulByte = 0;
896 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
898 analyze_format_string::OptionalAmount::HowSpecified::Constant)
903 std::optional<llvm::APSInt> DestSizeAPS =
908 unsigned DestSize = DestSizeAPS->getZExtValue();
910 if (DestSize < SourceSize)
917class EstimateSizeFormatHandler
922 bool IsKernelCompatible =
true;
925 EstimateSizeFormatHandler(StringRef Format)
926 :
Size(std::
min(Format.find(0), Format.size()) +
929 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
930 const char *,
unsigned SpecifierLen,
931 const TargetInfo &)
override {
933 const size_t FieldWidth = computeFieldWidth(FS);
934 const size_t Precision = computePrecision(FS);
941 Size += std::max(FieldWidth, (
size_t)1);
953 Size += std::max(FieldWidth, Precision);
969 Size += std::max(FieldWidth, 1 +
970 (Precision ? 1 + Precision
980 (Precision ? 1 + Precision : 0) +
990 (Precision ? 1 + Precision : 0) +
1005 IsKernelCompatible =
false;
1006 Size += std::max(FieldWidth, 2 + Precision);
1053 Size += (Precision ? 0 : 1);
1060 assert(SpecifierLen <= Size &&
"no underflow");
1061 Size -= SpecifierLen;
1065 size_t getSizeLowerBound()
const {
return Size; }
1066 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1069 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1070 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1071 size_t FieldWidth = 0;
1077 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1078 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1079 size_t Precision = 0;
1126 StringRef &FormatStrRef,
size_t &StrLen,
1128 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1129 Format && (Format->isOrdinary() || Format->isUTF8())) {
1130 FormatStrRef = Format->getString();
1132 Context.getAsConstantArrayType(Format->getType());
1133 assert(
T &&
"String literal not of constant array type!");
1134 size_t TypeSize =
T->getZExtSize();
1136 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1142void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1148 bool UseDABAttr =
false;
1149 const FunctionDecl *UseDecl = FD;
1151 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1153 UseDecl = DABAttr->getFunction();
1154 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1166 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1173 unsigned DABIndices = DABAttr->argIndices_size();
1174 unsigned NewIndex = Index < DABIndices
1175 ? DABAttr->argIndices_begin()[Index]
1178 return std::nullopt;
1182 auto ComputeExplicitObjectSizeArgument =
1183 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1184 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1186 return std::nullopt;
1187 unsigned NewIndex = *IndexOptional;
1189 Expr *SizeArg = TheCall->
getArg(NewIndex);
1191 return std::nullopt;
1197 auto ComputeSizeArgument =
1198 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1204 if (Index < FD->getNumParams()) {
1205 if (
const auto *POS =
1207 BOSType = POS->getType();
1210 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1212 return std::nullopt;
1213 unsigned NewIndex = *IndexOptional;
1216 return std::nullopt;
1218 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1221 return std::nullopt;
1224 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1227 auto ComputeStrLenArgument =
1228 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1229 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1231 return std::nullopt;
1232 unsigned NewIndex = *IndexOptional;
1234 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1237 return std::nullopt;
1239 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1242 std::optional<llvm::APSInt> SourceSize;
1243 std::optional<llvm::APSInt> DestinationSize;
1244 unsigned DiagID = 0;
1245 bool IsChkVariant =
false;
1247 auto GetFunctionName = [&]() {
1248 std::string FunctionNameStr =
1250 llvm::StringRef FunctionName = FunctionNameStr;
1255 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1256 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1258 FunctionName.consume_front(
"__builtin_");
1260 return FunctionName.str();
1263 switch (BuiltinID) {
1266 case Builtin::BI__builtin_stpcpy:
1267 case Builtin::BIstpcpy:
1268 case Builtin::BI__builtin_strcpy:
1269 case Builtin::BIstrcpy: {
1270 DiagID = diag::warn_fortify_strlen_overflow;
1271 SourceSize = ComputeStrLenArgument(1);
1272 DestinationSize = ComputeSizeArgument(0);
1276 case Builtin::BI__builtin___stpcpy_chk:
1277 case Builtin::BI__builtin___strcpy_chk: {
1278 DiagID = diag::warn_fortify_strlen_overflow;
1279 SourceSize = ComputeStrLenArgument(1);
1280 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1281 IsChkVariant =
true;
1285 case Builtin::BIscanf:
1286 case Builtin::BIfscanf:
1287 case Builtin::BIsscanf: {
1288 unsigned FormatIndex = 1;
1289 unsigned DataIndex = 2;
1290 if (BuiltinID == Builtin::BIscanf) {
1295 const auto *FormatExpr =
1298 StringRef FormatStrRef;
1303 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1304 unsigned SourceSize) {
1305 DiagID = diag::warn_fortify_scanf_overflow;
1306 unsigned Index = ArgIndex + DataIndex;
1307 std::string FunctionName = GetFunctionName();
1309 PDiag(DiagID) << FunctionName << (Index + 1)
1310 << DestSize << SourceSize);
1313 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1314 return ComputeSizeArgument(Index + DataIndex);
1316 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1317 const char *FormatBytes = FormatStrRef.data();
1328 case Builtin::BIsprintf:
1329 case Builtin::BI__builtin___sprintf_chk: {
1330 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1333 StringRef FormatStrRef;
1336 EstimateSizeFormatHandler H(FormatStrRef);
1337 const char *FormatBytes = FormatStrRef.data();
1339 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1340 Context.getTargetInfo(),
false)) {
1341 DiagID = H.isKernelCompatible()
1342 ? diag::warn_format_overflow
1343 : diag::warn_format_overflow_non_kprintf;
1344 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1345 .extOrTrunc(SizeTypeWidth);
1346 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1347 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1348 IsChkVariant =
true;
1350 DestinationSize = ComputeSizeArgument(0);
1357 case Builtin::BI__builtin___memcpy_chk:
1358 case Builtin::BI__builtin___memmove_chk:
1359 case Builtin::BI__builtin___memset_chk:
1360 case Builtin::BI__builtin___strlcat_chk:
1361 case Builtin::BI__builtin___strlcpy_chk:
1362 case Builtin::BI__builtin___strncat_chk:
1363 case Builtin::BI__builtin___strncpy_chk:
1364 case Builtin::BI__builtin___stpncpy_chk:
1365 case Builtin::BI__builtin___memccpy_chk:
1366 case Builtin::BI__builtin___mempcpy_chk: {
1367 DiagID = diag::warn_builtin_chk_overflow;
1368 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1370 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1371 IsChkVariant =
true;
1375 case Builtin::BI__builtin___snprintf_chk:
1376 case Builtin::BI__builtin___vsnprintf_chk: {
1377 DiagID = diag::warn_builtin_chk_overflow;
1378 SourceSize = ComputeExplicitObjectSizeArgument(1);
1379 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1380 IsChkVariant =
true;
1384 case Builtin::BIstrncat:
1385 case Builtin::BI__builtin_strncat:
1386 case Builtin::BIstrncpy:
1387 case Builtin::BI__builtin_strncpy:
1388 case Builtin::BIstpncpy:
1389 case Builtin::BI__builtin_stpncpy: {
1395 DiagID = diag::warn_fortify_source_size_mismatch;
1396 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397 DestinationSize = ComputeSizeArgument(0);
1401 case Builtin::BImemcpy:
1402 case Builtin::BI__builtin_memcpy:
1403 case Builtin::BImemmove:
1404 case Builtin::BI__builtin_memmove:
1405 case Builtin::BImemset:
1406 case Builtin::BI__builtin_memset:
1407 case Builtin::BImempcpy:
1408 case Builtin::BI__builtin_mempcpy: {
1409 DiagID = diag::warn_fortify_source_overflow;
1410 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1411 DestinationSize = ComputeSizeArgument(0);
1414 case Builtin::BIsnprintf:
1415 case Builtin::BI__builtin_snprintf:
1416 case Builtin::BIvsnprintf:
1417 case Builtin::BI__builtin_vsnprintf: {
1418 DiagID = diag::warn_fortify_source_size_mismatch;
1419 SourceSize = ComputeExplicitObjectSizeArgument(1);
1421 StringRef FormatStrRef;
1425 EstimateSizeFormatHandler H(FormatStrRef);
1426 const char *FormatBytes = FormatStrRef.data();
1428 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1429 Context.getTargetInfo(),
false)) {
1430 llvm::APSInt FormatSize =
1431 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1432 .extOrTrunc(SizeTypeWidth);
1433 if (FormatSize > *SourceSize && *SourceSize != 0) {
1434 unsigned TruncationDiagID =
1435 H.isKernelCompatible() ? diag::warn_format_truncation
1436 : diag::warn_format_truncation_non_kprintf;
1437 SmallString<16> SpecifiedSizeStr;
1438 SmallString<16> FormatSizeStr;
1439 SourceSize->toString(SpecifiedSizeStr, 10);
1440 FormatSize.toString(FormatSizeStr, 10);
1442 PDiag(TruncationDiagID)
1443 << GetFunctionName() << SpecifiedSizeStr
1448 DestinationSize = ComputeSizeArgument(0);
1452 if (!SourceSize || !DestinationSize ||
1453 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1456 std::string FunctionName = GetFunctionName();
1458 SmallString<16> DestinationStr;
1459 SmallString<16> SourceStr;
1460 DestinationSize->toString(DestinationStr, 10);
1461 SourceSize->toString(SourceStr, 10);
1464 << FunctionName << DestinationStr << SourceStr);
1479 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1482 << DRE->getDecl()->getIdentifier();
1494 "__builtin_alloca has invalid address space");
1502enum PointerAuthOpKind {
1517 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1548 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1551 llvm::raw_svector_ostream Str(
Value);
1560 Result = KeyValue->getZExtValue();
1579 bool IsAddrDiscArg =
false;
1584 IsAddrDiscArg =
true;
1593 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1594 <<
Result->getExtValue();
1596 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1602 IntVal =
Result->getZExtValue();
1606static std::pair<const ValueDecl *, CharUnits>
1613 const auto *BaseDecl =
1618 return {BaseDecl, Result.Val.getLValueOffset()};
1622 bool RequireConstant =
false) {
1630 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1631 return OpKind != PAO_BlendInteger;
1633 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1634 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1635 OpKind == PAO_SignGeneric;
1644 }
else if (AllowsInteger(OpKind) &&
1651 <<
unsigned(OpKind == PAO_Discriminator ? 1
1652 : OpKind == PAO_BlendPointer ? 2
1653 : OpKind == PAO_BlendInteger ? 3
1655 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1665 if (!RequireConstant) {
1667 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1670 ? diag::warn_ptrauth_sign_null_pointer
1671 : diag::warn_ptrauth_auth_null_pointer)
1681 if (OpKind == PAO_Sign) {
1699 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1704 assert(OpKind == PAO_Discriminator);
1710 if (
Call->getBuiltinCallee() ==
1711 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1726 assert(
Pointer->getType()->isPointerType());
1738 assert(
Integer->getType()->isIntegerType());
1744 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1757 Call->setType(
Call->getArgs()[0]->getType());
1788 PointerAuthOpKind OpKind,
1789 bool RequireConstant) {
1800 Call->setType(
Call->getArgs()[0]->getType());
1816 Call->setType(
Call->getArgs()[0]->getType());
1825 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1828 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1829 if (!Literal || Literal->getCharByteWidth() != 1) {
1845 Call->setArg(0, FirstValue.
get());
1851 if (!FirstArgRecord) {
1852 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1853 << 0 << FirstArgType;
1858 diag::err_get_vtable_pointer_requires_complete_type)) {
1863 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1864 << 1 << FirstArgRecord;
1868 Call->setType(ReturnType);
1893 auto DiagSelect = [&]() -> std::optional<unsigned> {
1900 return std::optional<unsigned>{};
1915 diag::err_incomplete_type))
1919 "Unhandled non-object pointer case");
1947 if (PT->getPointeeType()->isFunctionType()) {
1949 diag::err_builtin_is_within_lifetime_invalid_arg)
1955 if (PT->getPointeeType()->isVariableArrayType()) {
1957 << 1 <<
"__builtin_is_within_lifetime";
1962 diag::err_builtin_is_within_lifetime_invalid_arg)
1976 diag::err_builtin_trivially_relocate_invalid_arg_type)
1983 diag::err_incomplete_type))
1987 T->isIncompleteArrayType()) {
1989 diag::err_builtin_trivially_relocate_invalid_arg_type)
1990 << (
T.isConstQualified() ? 1 : 2);
1999 diag::err_builtin_trivially_relocate_invalid_arg_type)
2006 if (Size.isInvalid())
2010 if (Size.isInvalid())
2012 SizeExpr = Size.get();
2013 TheCall->
setArg(2, SizeExpr);
2023 llvm::Triple::ObjectFormatType CurObjFormat =
2025 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2038 llvm::Triple::ArchType CurArch =
2040 if (llvm::is_contained(SupportedArchs, CurArch))
2050bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2057 case llvm::Triple::arm:
2058 case llvm::Triple::armeb:
2059 case llvm::Triple::thumb:
2060 case llvm::Triple::thumbeb:
2062 case llvm::Triple::aarch64:
2063 case llvm::Triple::aarch64_32:
2064 case llvm::Triple::aarch64_be:
2066 case llvm::Triple::bpfeb:
2067 case llvm::Triple::bpfel:
2069 case llvm::Triple::dxil:
2071 case llvm::Triple::hexagon:
2073 case llvm::Triple::mips:
2074 case llvm::Triple::mipsel:
2075 case llvm::Triple::mips64:
2076 case llvm::Triple::mips64el:
2078 case llvm::Triple::spirv:
2079 case llvm::Triple::spirv32:
2080 case llvm::Triple::spirv64:
2081 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2084 case llvm::Triple::systemz:
2086 case llvm::Triple::x86:
2087 case llvm::Triple::x86_64:
2089 case llvm::Triple::ppc:
2090 case llvm::Triple::ppcle:
2091 case llvm::Triple::ppc64:
2092 case llvm::Triple::ppc64le:
2094 case llvm::Triple::amdgcn:
2096 case llvm::Triple::riscv32:
2097 case llvm::Triple::riscv64:
2099 case llvm::Triple::loongarch32:
2100 case llvm::Triple::loongarch64:
2103 case llvm::Triple::wasm32:
2104 case llvm::Triple::wasm64:
2106 case llvm::Triple::nvptx:
2107 case llvm::Triple::nvptx64:
2121 EltTy = VecTy->getElementType();
2123 switch (ArgTyRestr) {
2127 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2128 << ArgOrdinal << 2 << 1 << 1
2134 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2135 << ArgOrdinal << 5 << 0
2141 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2142 << ArgOrdinal << 5 << 1
2148 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2162 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2163 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2164 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2165 "Expecting __builtin_cpu_...");
2167 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2169 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2170 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2171 (!IsCPUSupports && TInfo->supportsCpuIs()));
2173 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2180 ? diag::err_builtin_aix_os_unsupported
2181 : diag::err_builtin_target_unsupported)
2187 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2239 TheCall->
setArg(0, Arg0);
2256 TheCall->
setArg(1, Arg1);
2262 << 2 << 1 << 4 << 0 << Arg1Ty;
2274 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2279 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2280 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2281 << Pos <<
"scalar pointer";
2305 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2329 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2339 diag::err_vec_builtin_incompatible_vector)
2361 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2374 << MaskTy << IdxTy);
2383 diag::err_vec_masked_load_store_ptr)
2406 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2422 << MaskTy << IdxTy);
2428 << MaskTy << ValTy);
2434 diag::err_vec_builtin_incompatible_vector)
2448 if (Args.size() == 0) {
2450 diag::err_typecheck_call_too_few_args_at_least)
2456 QualType FuncT = Args[0]->getType();
2459 if (Args.size() < 2) {
2461 diag::err_typecheck_call_too_few_args_at_least)
2467 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2468 QualType ObjectT = Args[1]->getType();
2470 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2519 tok::periodstar, ObjectArg.
get(), Args[0]);
2523 if (MPT->isMemberDataPointer())
2526 auto *MemCall =
new (S.
Context)
2537Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2542 unsigned ICEArguments = 0;
2544 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2549 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2551 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2556 if (ArgNo < TheCall->getNumArgs() &&
2559 ICEArguments &= ~(1 << ArgNo);
2563 switch (BuiltinID) {
2564 case Builtin::BI__builtin_cpu_supports:
2565 case Builtin::BI__builtin_cpu_is:
2567 Context.getAuxTargetInfo(), BuiltinID))
2570 case Builtin::BI__builtin_cpu_init:
2571 if (!
Context.getTargetInfo().supportsCpuInit()) {
2577 case Builtin::BI__builtin___CFStringMakeConstantString:
2581 *
this, BuiltinID, TheCall,
2582 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2585 "Wrong # arguments to builtin CFStringMakeConstantString");
2586 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2589 case Builtin::BI__builtin_ms_va_start:
2590 case Builtin::BI__builtin_stdarg_start:
2591 case Builtin::BI__builtin_va_start:
2592 case Builtin::BI__builtin_c23_va_start:
2593 if (BuiltinVAStart(BuiltinID, TheCall))
2596 case Builtin::BI__va_start: {
2597 switch (
Context.getTargetInfo().getTriple().getArch()) {
2598 case llvm::Triple::aarch64:
2599 case llvm::Triple::arm:
2600 case llvm::Triple::thumb:
2601 if (BuiltinVAStartARMMicrosoft(TheCall))
2605 if (BuiltinVAStart(BuiltinID, TheCall))
2613 case Builtin::BI_interlockedbittestandset_acq:
2614 case Builtin::BI_interlockedbittestandset_rel:
2615 case Builtin::BI_interlockedbittestandset_nf:
2616 case Builtin::BI_interlockedbittestandreset_acq:
2617 case Builtin::BI_interlockedbittestandreset_rel:
2618 case Builtin::BI_interlockedbittestandreset_nf:
2621 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2626 case Builtin::BI_bittest64:
2627 case Builtin::BI_bittestandcomplement64:
2628 case Builtin::BI_bittestandreset64:
2629 case Builtin::BI_bittestandset64:
2630 case Builtin::BI_interlockedbittestandreset64:
2631 case Builtin::BI_interlockedbittestandset64:
2634 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2635 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2640 case Builtin::BI_interlockedbittestandreset64_acq:
2641 case Builtin::BI_interlockedbittestandreset64_rel:
2642 case Builtin::BI_interlockedbittestandreset64_nf:
2643 case Builtin::BI_interlockedbittestandset64_acq:
2644 case Builtin::BI_interlockedbittestandset64_rel:
2645 case Builtin::BI_interlockedbittestandset64_nf:
2650 case Builtin::BI__builtin_set_flt_rounds:
2653 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2654 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2655 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2656 llvm::Triple::ppc64le}))
2660 case Builtin::BI__builtin_isgreater:
2661 case Builtin::BI__builtin_isgreaterequal:
2662 case Builtin::BI__builtin_isless:
2663 case Builtin::BI__builtin_islessequal:
2664 case Builtin::BI__builtin_islessgreater:
2665 case Builtin::BI__builtin_isunordered:
2666 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2669 case Builtin::BI__builtin_fpclassify:
2670 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2673 case Builtin::BI__builtin_isfpclass:
2674 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2677 case Builtin::BI__builtin_isfinite:
2678 case Builtin::BI__builtin_isinf:
2679 case Builtin::BI__builtin_isinf_sign:
2680 case Builtin::BI__builtin_isnan:
2681 case Builtin::BI__builtin_issignaling:
2682 case Builtin::BI__builtin_isnormal:
2683 case Builtin::BI__builtin_issubnormal:
2684 case Builtin::BI__builtin_iszero:
2685 case Builtin::BI__builtin_signbit:
2686 case Builtin::BI__builtin_signbitf:
2687 case Builtin::BI__builtin_signbitl:
2688 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2691 case Builtin::BI__builtin_shufflevector:
2695 case Builtin::BI__builtin_masked_load:
2696 case Builtin::BI__builtin_masked_expand_load:
2698 case Builtin::BI__builtin_masked_store:
2699 case Builtin::BI__builtin_masked_compress_store:
2701 case Builtin::BI__builtin_masked_gather:
2703 case Builtin::BI__builtin_masked_scatter:
2705 case Builtin::BI__builtin_invoke:
2707 case Builtin::BI__builtin_prefetch:
2708 if (BuiltinPrefetch(TheCall))
2711 case Builtin::BI__builtin_alloca_with_align:
2712 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2713 if (BuiltinAllocaWithAlign(TheCall))
2716 case Builtin::BI__builtin_alloca:
2717 case Builtin::BI__builtin_alloca_uninitialized:
2724 case Builtin::BI__arithmetic_fence:
2725 if (BuiltinArithmeticFence(TheCall))
2728 case Builtin::BI__assume:
2729 case Builtin::BI__builtin_assume:
2730 if (BuiltinAssume(TheCall))
2733 case Builtin::BI__builtin_assume_aligned:
2734 if (BuiltinAssumeAligned(TheCall))
2737 case Builtin::BI__builtin_dynamic_object_size:
2738 case Builtin::BI__builtin_object_size:
2742 case Builtin::BI__builtin_longjmp:
2743 if (BuiltinLongjmp(TheCall))
2746 case Builtin::BI__builtin_setjmp:
2747 if (BuiltinSetjmp(TheCall))
2750 case Builtin::BI__builtin_classify_type:
2755 case Builtin::BI__builtin_complex:
2756 if (BuiltinComplex(TheCall))
2759 case Builtin::BI__builtin_constant_p: {
2768 case Builtin::BI__builtin_launder:
2770 case Builtin::BI__builtin_is_within_lifetime:
2772 case Builtin::BI__builtin_trivially_relocate:
2775 case Builtin::BI__sync_fetch_and_add:
2776 case Builtin::BI__sync_fetch_and_add_1:
2777 case Builtin::BI__sync_fetch_and_add_2:
2778 case Builtin::BI__sync_fetch_and_add_4:
2779 case Builtin::BI__sync_fetch_and_add_8:
2780 case Builtin::BI__sync_fetch_and_add_16:
2781 case Builtin::BI__sync_fetch_and_sub:
2782 case Builtin::BI__sync_fetch_and_sub_1:
2783 case Builtin::BI__sync_fetch_and_sub_2:
2784 case Builtin::BI__sync_fetch_and_sub_4:
2785 case Builtin::BI__sync_fetch_and_sub_8:
2786 case Builtin::BI__sync_fetch_and_sub_16:
2787 case Builtin::BI__sync_fetch_and_or:
2788 case Builtin::BI__sync_fetch_and_or_1:
2789 case Builtin::BI__sync_fetch_and_or_2:
2790 case Builtin::BI__sync_fetch_and_or_4:
2791 case Builtin::BI__sync_fetch_and_or_8:
2792 case Builtin::BI__sync_fetch_and_or_16:
2793 case Builtin::BI__sync_fetch_and_and:
2794 case Builtin::BI__sync_fetch_and_and_1:
2795 case Builtin::BI__sync_fetch_and_and_2:
2796 case Builtin::BI__sync_fetch_and_and_4:
2797 case Builtin::BI__sync_fetch_and_and_8:
2798 case Builtin::BI__sync_fetch_and_and_16:
2799 case Builtin::BI__sync_fetch_and_xor:
2800 case Builtin::BI__sync_fetch_and_xor_1:
2801 case Builtin::BI__sync_fetch_and_xor_2:
2802 case Builtin::BI__sync_fetch_and_xor_4:
2803 case Builtin::BI__sync_fetch_and_xor_8:
2804 case Builtin::BI__sync_fetch_and_xor_16:
2805 case Builtin::BI__sync_fetch_and_nand:
2806 case Builtin::BI__sync_fetch_and_nand_1:
2807 case Builtin::BI__sync_fetch_and_nand_2:
2808 case Builtin::BI__sync_fetch_and_nand_4:
2809 case Builtin::BI__sync_fetch_and_nand_8:
2810 case Builtin::BI__sync_fetch_and_nand_16:
2811 case Builtin::BI__sync_add_and_fetch:
2812 case Builtin::BI__sync_add_and_fetch_1:
2813 case Builtin::BI__sync_add_and_fetch_2:
2814 case Builtin::BI__sync_add_and_fetch_4:
2815 case Builtin::BI__sync_add_and_fetch_8:
2816 case Builtin::BI__sync_add_and_fetch_16:
2817 case Builtin::BI__sync_sub_and_fetch:
2818 case Builtin::BI__sync_sub_and_fetch_1:
2819 case Builtin::BI__sync_sub_and_fetch_2:
2820 case Builtin::BI__sync_sub_and_fetch_4:
2821 case Builtin::BI__sync_sub_and_fetch_8:
2822 case Builtin::BI__sync_sub_and_fetch_16:
2823 case Builtin::BI__sync_and_and_fetch:
2824 case Builtin::BI__sync_and_and_fetch_1:
2825 case Builtin::BI__sync_and_and_fetch_2:
2826 case Builtin::BI__sync_and_and_fetch_4:
2827 case Builtin::BI__sync_and_and_fetch_8:
2828 case Builtin::BI__sync_and_and_fetch_16:
2829 case Builtin::BI__sync_or_and_fetch:
2830 case Builtin::BI__sync_or_and_fetch_1:
2831 case Builtin::BI__sync_or_and_fetch_2:
2832 case Builtin::BI__sync_or_and_fetch_4:
2833 case Builtin::BI__sync_or_and_fetch_8:
2834 case Builtin::BI__sync_or_and_fetch_16:
2835 case Builtin::BI__sync_xor_and_fetch:
2836 case Builtin::BI__sync_xor_and_fetch_1:
2837 case Builtin::BI__sync_xor_and_fetch_2:
2838 case Builtin::BI__sync_xor_and_fetch_4:
2839 case Builtin::BI__sync_xor_and_fetch_8:
2840 case Builtin::BI__sync_xor_and_fetch_16:
2841 case Builtin::BI__sync_nand_and_fetch:
2842 case Builtin::BI__sync_nand_and_fetch_1:
2843 case Builtin::BI__sync_nand_and_fetch_2:
2844 case Builtin::BI__sync_nand_and_fetch_4:
2845 case Builtin::BI__sync_nand_and_fetch_8:
2846 case Builtin::BI__sync_nand_and_fetch_16:
2847 case Builtin::BI__sync_val_compare_and_swap:
2848 case Builtin::BI__sync_val_compare_and_swap_1:
2849 case Builtin::BI__sync_val_compare_and_swap_2:
2850 case Builtin::BI__sync_val_compare_and_swap_4:
2851 case Builtin::BI__sync_val_compare_and_swap_8:
2852 case Builtin::BI__sync_val_compare_and_swap_16:
2853 case Builtin::BI__sync_bool_compare_and_swap:
2854 case Builtin::BI__sync_bool_compare_and_swap_1:
2855 case Builtin::BI__sync_bool_compare_and_swap_2:
2856 case Builtin::BI__sync_bool_compare_and_swap_4:
2857 case Builtin::BI__sync_bool_compare_and_swap_8:
2858 case Builtin::BI__sync_bool_compare_and_swap_16:
2859 case Builtin::BI__sync_lock_test_and_set:
2860 case Builtin::BI__sync_lock_test_and_set_1:
2861 case Builtin::BI__sync_lock_test_and_set_2:
2862 case Builtin::BI__sync_lock_test_and_set_4:
2863 case Builtin::BI__sync_lock_test_and_set_8:
2864 case Builtin::BI__sync_lock_test_and_set_16:
2865 case Builtin::BI__sync_lock_release:
2866 case Builtin::BI__sync_lock_release_1:
2867 case Builtin::BI__sync_lock_release_2:
2868 case Builtin::BI__sync_lock_release_4:
2869 case Builtin::BI__sync_lock_release_8:
2870 case Builtin::BI__sync_lock_release_16:
2871 case Builtin::BI__sync_swap:
2872 case Builtin::BI__sync_swap_1:
2873 case Builtin::BI__sync_swap_2:
2874 case Builtin::BI__sync_swap_4:
2875 case Builtin::BI__sync_swap_8:
2876 case Builtin::BI__sync_swap_16:
2877 return BuiltinAtomicOverloaded(TheCallResult);
2878 case Builtin::BI__sync_synchronize:
2882 case Builtin::BI__builtin_nontemporal_load:
2883 case Builtin::BI__builtin_nontemporal_store:
2884 return BuiltinNontemporalOverloaded(TheCallResult);
2885 case Builtin::BI__builtin_memcpy_inline: {
2886 clang::Expr *SizeOp = TheCall->
getArg(2);
2898 case Builtin::BI__builtin_memset_inline: {
2899 clang::Expr *SizeOp = TheCall->
getArg(2);
2909#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2910 case Builtin::BI##ID: \
2911 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2912#include "clang/Basic/Builtins.inc"
2913 case Builtin::BI__annotation:
2917 case Builtin::BI__builtin_annotation:
2921 case Builtin::BI__builtin_addressof:
2925 case Builtin::BI__builtin_function_start:
2929 case Builtin::BI__builtin_is_aligned:
2930 case Builtin::BI__builtin_align_up:
2931 case Builtin::BI__builtin_align_down:
2935 case Builtin::BI__builtin_add_overflow:
2936 case Builtin::BI__builtin_sub_overflow:
2937 case Builtin::BI__builtin_mul_overflow:
2941 case Builtin::BI__builtin_operator_new:
2942 case Builtin::BI__builtin_operator_delete: {
2943 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2945 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2948 case Builtin::BI__builtin_dump_struct:
2950 case Builtin::BI__builtin_expect_with_probability: {
2955 const Expr *ProbArg = TheCall->
getArg(2);
2956 SmallVector<PartialDiagnosticAt, 8> Notes;
2957 Expr::EvalResult Eval;
2961 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2968 bool LoseInfo =
false;
2969 Probability.convert(llvm::APFloat::IEEEdouble(),
2970 llvm::RoundingMode::Dynamic, &LoseInfo);
2971 if (!(Probability >= llvm::APFloat(0.0) &&
2972 Probability <= llvm::APFloat(1.0))) {
2979 case Builtin::BI__builtin_preserve_access_index:
2983 case Builtin::BI__builtin_call_with_static_chain:
2987 case Builtin::BI__exception_code:
2988 case Builtin::BI_exception_code:
2990 diag::err_seh___except_block))
2993 case Builtin::BI__exception_info:
2994 case Builtin::BI_exception_info:
2996 diag::err_seh___except_filter))
2999 case Builtin::BI__GetExceptionInfo:
3011 case Builtin::BIaddressof:
3012 case Builtin::BI__addressof:
3013 case Builtin::BIforward:
3014 case Builtin::BIforward_like:
3015 case Builtin::BImove:
3016 case Builtin::BImove_if_noexcept:
3017 case Builtin::BIas_const: {
3025 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3026 BuiltinID == Builtin::BI__addressof;
3028 (ReturnsPointer ?
Result->isAnyPointerType()
3029 :
Result->isReferenceType()) &&
3032 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3038 case Builtin::BI__builtin_ptrauth_strip:
3040 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3042 case Builtin::BI__builtin_ptrauth_sign_constant:
3045 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3048 case Builtin::BI__builtin_ptrauth_auth:
3051 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3053 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3055 case Builtin::BI__builtin_ptrauth_string_discriminator:
3058 case Builtin::BI__builtin_get_vtable_pointer:
3062 case Builtin::BIread_pipe:
3063 case Builtin::BIwrite_pipe:
3066 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3069 case Builtin::BIreserve_read_pipe:
3070 case Builtin::BIreserve_write_pipe:
3071 case Builtin::BIwork_group_reserve_read_pipe:
3072 case Builtin::BIwork_group_reserve_write_pipe:
3073 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3076 case Builtin::BIsub_group_reserve_read_pipe:
3077 case Builtin::BIsub_group_reserve_write_pipe:
3078 if (
OpenCL().checkSubgroupExt(TheCall) ||
3079 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3082 case Builtin::BIcommit_read_pipe:
3083 case Builtin::BIcommit_write_pipe:
3084 case Builtin::BIwork_group_commit_read_pipe:
3085 case Builtin::BIwork_group_commit_write_pipe:
3086 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3089 case Builtin::BIsub_group_commit_read_pipe:
3090 case Builtin::BIsub_group_commit_write_pipe:
3091 if (
OpenCL().checkSubgroupExt(TheCall) ||
3092 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3095 case Builtin::BIget_pipe_num_packets:
3096 case Builtin::BIget_pipe_max_packets:
3097 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3100 case Builtin::BIto_global:
3101 case Builtin::BIto_local:
3102 case Builtin::BIto_private:
3103 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3107 case Builtin::BIenqueue_kernel:
3108 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3111 case Builtin::BIget_kernel_work_group_size:
3112 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3113 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3116 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3117 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3118 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3121 case Builtin::BI__builtin_os_log_format:
3122 Cleanup.setExprNeedsCleanups(
true);
3124 case Builtin::BI__builtin_os_log_format_buffer_size:
3125 if (BuiltinOSLogFormat(TheCall))
3128 case Builtin::BI__builtin_frame_address:
3129 case Builtin::BI__builtin_return_address: {
3138 Result.Val.getInt() != 0)
3140 << ((BuiltinID == Builtin::BI__builtin_return_address)
3141 ?
"__builtin_return_address"
3142 :
"__builtin_frame_address")
3147 case Builtin::BI__builtin_nondeterministic_value: {
3148 if (BuiltinNonDeterministicValue(TheCall))
3155 case Builtin::BI__builtin_elementwise_abs:
3163 case Builtin::BI__builtin_elementwise_acos:
3164 case Builtin::BI__builtin_elementwise_asin:
3165 case Builtin::BI__builtin_elementwise_atan:
3166 case Builtin::BI__builtin_elementwise_ceil:
3167 case Builtin::BI__builtin_elementwise_cos:
3168 case Builtin::BI__builtin_elementwise_cosh:
3169 case Builtin::BI__builtin_elementwise_exp:
3170 case Builtin::BI__builtin_elementwise_exp2:
3171 case Builtin::BI__builtin_elementwise_exp10:
3172 case Builtin::BI__builtin_elementwise_floor:
3173 case Builtin::BI__builtin_elementwise_log:
3174 case Builtin::BI__builtin_elementwise_log2:
3175 case Builtin::BI__builtin_elementwise_log10:
3176 case Builtin::BI__builtin_elementwise_roundeven:
3177 case Builtin::BI__builtin_elementwise_round:
3178 case Builtin::BI__builtin_elementwise_rint:
3179 case Builtin::BI__builtin_elementwise_nearbyint:
3180 case Builtin::BI__builtin_elementwise_sin:
3181 case Builtin::BI__builtin_elementwise_sinh:
3182 case Builtin::BI__builtin_elementwise_sqrt:
3183 case Builtin::BI__builtin_elementwise_tan:
3184 case Builtin::BI__builtin_elementwise_tanh:
3185 case Builtin::BI__builtin_elementwise_trunc:
3186 case Builtin::BI__builtin_elementwise_canonicalize:
3191 case Builtin::BI__builtin_elementwise_fma:
3198 case Builtin::BI__builtin_elementwise_minnum:
3199 case Builtin::BI__builtin_elementwise_maxnum:
3200 case Builtin::BI__builtin_elementwise_minimum:
3201 case Builtin::BI__builtin_elementwise_maximum:
3202 case Builtin::BI__builtin_elementwise_minimumnum:
3203 case Builtin::BI__builtin_elementwise_maximumnum:
3204 case Builtin::BI__builtin_elementwise_atan2:
3205 case Builtin::BI__builtin_elementwise_fmod:
3206 case Builtin::BI__builtin_elementwise_pow:
3207 if (BuiltinElementwiseMath(TheCall,
3213 case Builtin::BI__builtin_elementwise_add_sat:
3214 case Builtin::BI__builtin_elementwise_sub_sat:
3215 if (BuiltinElementwiseMath(TheCall,
3219 case Builtin::BI__builtin_elementwise_fshl:
3220 case Builtin::BI__builtin_elementwise_fshr:
3225 case Builtin::BI__builtin_elementwise_min:
3226 case Builtin::BI__builtin_elementwise_max:
3227 if (BuiltinElementwiseMath(TheCall))
3230 case Builtin::BI__builtin_elementwise_popcount:
3231 case Builtin::BI__builtin_elementwise_bitreverse:
3236 case Builtin::BI__builtin_elementwise_copysign: {
3245 QualType MagnitudeTy = Magnitude.
get()->
getType();
3258 diag::err_typecheck_call_different_arg_types)
3259 << MagnitudeTy << SignTy;
3267 case Builtin::BI__builtin_elementwise_clzg:
3268 case Builtin::BI__builtin_elementwise_ctzg:
3276 }
else if (BuiltinElementwiseMath(
3280 case Builtin::BI__builtin_reduce_max:
3281 case Builtin::BI__builtin_reduce_min: {
3282 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3285 const Expr *Arg = TheCall->
getArg(0);
3290 ElTy = TyA->getElementType();
3294 if (ElTy.isNull()) {
3304 case Builtin::BI__builtin_reduce_maximum:
3305 case Builtin::BI__builtin_reduce_minimum: {
3306 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3309 const Expr *Arg = TheCall->
getArg(0);
3314 ElTy = TyA->getElementType();
3318 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3331 case Builtin::BI__builtin_reduce_add:
3332 case Builtin::BI__builtin_reduce_mul:
3333 case Builtin::BI__builtin_reduce_xor:
3334 case Builtin::BI__builtin_reduce_or:
3335 case Builtin::BI__builtin_reduce_and: {
3336 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3339 const Expr *Arg = TheCall->
getArg(0);
3344 ElTy = TyA->getElementType();
3348 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3359 case Builtin::BI__builtin_matrix_transpose:
3360 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3362 case Builtin::BI__builtin_matrix_column_major_load:
3363 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3365 case Builtin::BI__builtin_matrix_column_major_store:
3366 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3368 case Builtin::BI__builtin_verbose_trap:
3373 case Builtin::BI__builtin_get_device_side_mangled_name: {
3374 auto Check = [](CallExpr *TheCall) {
3380 auto *D = DRE->getDecl();
3383 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3384 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3386 if (!Check(TheCall)) {
3388 diag::err_hip_invalid_args_builtin_mangled_name);
3393 case Builtin::BI__builtin_popcountg:
3397 case Builtin::BI__builtin_clzg:
3398 case Builtin::BI__builtin_ctzg:
3403 case Builtin::BI__builtin_allow_runtime_check: {
3404 Expr *Arg = TheCall->
getArg(0);
3413 case Builtin::BI__builtin_counted_by_ref:
3414 if (BuiltinCountedByRef(TheCall))
3424 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3425 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3426 assert(
Context.getAuxTargetInfo() &&
3427 "Aux Target Builtin, but not an aux target?");
3429 if (CheckTSBuiltinFunctionCall(
3431 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3434 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3440 return TheCallResult;
3455 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3459 diag::err_argument_not_contiguous_bit_field)
3465 bool IsCXXMember =
false;
3466 if (
const auto *MD = dyn_cast<CXXMethodDecl>(D))
3467 IsCXXMember = MD->isInstance();
3468 bool IsVariadic =
false;
3471 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3472 IsVariadic = BD->isVariadic();
3473 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3474 IsVariadic = OMD->isVariadic();
3480 bool IsCXXMember,
bool IsVariadic,
3484 else if (IsVariadic)
3525 UT && UT->getOriginalDecl()
3526 ->getMostRecentDecl()
3527 ->hasAttr<TransparentUnionAttr>()) {
3528 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3529 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3530 Expr = ILE->getInit(0);
3540 const Expr *ArgExpr,
3544 S.
PDiag(diag::warn_null_arg)
3550 if (
auto nullability =
type->getNullability())
3561 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3567 llvm::SmallBitVector NonNullArgs;
3573 for (
const auto *Arg : Args)
3580 unsigned IdxAST = Idx.getASTIndex();
3581 if (IdxAST >= Args.size())
3583 if (NonNullArgs.empty())
3584 NonNullArgs.resize(Args.size());
3585 NonNullArgs.set(IdxAST);
3594 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3599 unsigned ParamIndex = 0;
3601 I != E; ++I, ++ParamIndex) {
3604 if (NonNullArgs.empty())
3605 NonNullArgs.resize(Args.size());
3607 NonNullArgs.set(ParamIndex);
3614 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3619 type = blockType->getPointeeType();
3633 if (NonNullArgs.empty())
3634 NonNullArgs.resize(Args.size());
3636 NonNullArgs.set(Index);
3645 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3646 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3647 if (NonNullArgs[ArgIndex])
3653 StringRef ParamName,
QualType ArgTy,
3676 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3677 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3681 if (ArgAlign < ParamAlign)
3682 Diag(Loc, diag::warn_param_mismatched_alignment)
3684 << ParamName << (FDecl !=
nullptr) << FDecl;
3688 const Expr *ThisArg,
3690 if (!FD || Args.empty())
3692 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3693 if (Idx == LifetimeCaptureByAttr::Global ||
3694 Idx == LifetimeCaptureByAttr::Unknown)
3696 if (IsMemberFunction && Idx == 0)
3698 return Args[Idx - IsMemberFunction];
3700 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3705 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3706 for (
int CapturingParamIdx :
Attr->params()) {
3709 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3712 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3720 I + IsMemberFunction);
3722 if (IsMemberFunction) {
3730 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3743 llvm::SmallBitVector CheckedVarArgs;
3745 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3747 CheckedVarArgs.resize(Args.size());
3748 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3753 CheckedVarArgs.resize(Args.size());
3754 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3761 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3765 : isa_and_nonnull<FunctionDecl>(FDecl)
3767 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3771 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3773 if (
const Expr *Arg = Args[ArgIdx]) {
3774 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3781 if (FDecl || Proto) {
3786 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3787 CheckArgumentWithTypeTag(I, Args, Loc);
3793 if (!Proto && FDecl) {
3795 if (isa_and_nonnull<FunctionProtoType>(FT))
3801 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3803 bool IsScalableArg =
false;
3804 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3806 if (
const Expr *Arg = Args[ArgIdx]) {
3810 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3818 IsScalableArg =
true;
3820 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3829 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3830 llvm::StringMap<bool> CallerFeatureMap;
3831 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
3832 if (!CallerFeatureMap.contains(
"sme"))
3833 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3834 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
3835 Diag(Loc, diag::err_sme_call_in_non_sme_target);
3844 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3846 (IsScalableArg || IsScalableRet)) {
3847 bool IsCalleeStreaming =
3849 bool IsCalleeStreamingCompatible =
3853 if (!IsCalleeStreamingCompatible &&
3857 unsigned VL = LO.VScaleMin * 128;
3858 unsigned SVL = LO.VScaleStreamingMin * 128;
3859 bool IsVLMismatch = VL && SVL && VL != SVL;
3861 auto EmitDiag = [&](
bool IsArg) {
3865 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
3866 << IsArg << IsCalleeStreaming << SVL << VL;
3869 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
3870 << IsArg << SVL << VL;
3872 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3889 bool CallerHasZAState =
false;
3890 bool CallerHasZT0State =
false;
3892 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3894 CallerHasZAState =
true;
3896 CallerHasZT0State =
true;
3900 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3902 CallerHasZT0State |=
3904 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3910 Diag(Loc, diag::err_sme_za_call_no_za_state);
3913 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
3917 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
3918 Diag(Loc, diag::note_sme_use_preserves_za);
3923 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3924 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3925 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3926 if (!Arg->isValueDependent()) {
3928 if (Arg->EvaluateAsInt(Align,
Context)) {
3929 const llvm::APSInt &I = Align.
Val.
getInt();
3930 if (!I.isPowerOf2())
3931 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3932 << Arg->getSourceRange();
3935 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3961 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
3962 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
3964 checkCall(FDecl, Proto,
nullptr, Args,
true,
3973 IsMemberOperatorCall;
3979 Expr *ImplicitThis =
nullptr;
3984 ImplicitThis = Args[0];
3987 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3998 ThisType =
Context.getPointerType(ThisType);
4004 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4022 CheckAbsoluteValueFunction(TheCall, FDecl);
4023 CheckMaxUnsignedZero(TheCall, FDecl);
4024 CheckInfNaNFunction(TheCall, FDecl);
4035 case Builtin::BIstrlcpy:
4036 case Builtin::BIstrlcat:
4037 CheckStrlcpycatArguments(TheCall, FnInfo);
4039 case Builtin::BIstrncat:
4040 CheckStrncatArguments(TheCall, FnInfo);
4042 case Builtin::BIfree:
4043 CheckFreeArguments(TheCall);
4046 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4055 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4056 Ty =
V->getType().getNonReferenceType();
4057 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4058 Ty = F->getType().getNonReferenceType();
4095 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4098 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4100 case AtomicExpr::AO__c11_atomic_init:
4101 case AtomicExpr::AO__opencl_atomic_init:
4102 llvm_unreachable(
"There is no ordering argument for an init");
4104 case AtomicExpr::AO__c11_atomic_load:
4105 case AtomicExpr::AO__opencl_atomic_load:
4106 case AtomicExpr::AO__hip_atomic_load:
4107 case AtomicExpr::AO__atomic_load_n:
4108 case AtomicExpr::AO__atomic_load:
4109 case AtomicExpr::AO__scoped_atomic_load_n:
4110 case AtomicExpr::AO__scoped_atomic_load:
4111 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4112 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4114 case AtomicExpr::AO__c11_atomic_store:
4115 case AtomicExpr::AO__opencl_atomic_store:
4116 case AtomicExpr::AO__hip_atomic_store:
4117 case AtomicExpr::AO__atomic_store:
4118 case AtomicExpr::AO__atomic_store_n:
4119 case AtomicExpr::AO__scoped_atomic_store:
4120 case AtomicExpr::AO__scoped_atomic_store_n:
4121 case AtomicExpr::AO__atomic_clear:
4122 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4123 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4124 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4183 const unsigned NumForm = ClearByte + 1;
4184 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4185 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4193 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4194 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4195 "need to update code for modified forms");
4196 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4197 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4198 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4199 "need to update code for modified C11 atomics");
4200 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4201 Op <= AtomicExpr::AO__opencl_atomic_store;
4202 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4203 Op <= AtomicExpr::AO__hip_atomic_store;
4204 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4205 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4206 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4207 Op <= AtomicExpr::AO__c11_atomic_store) ||
4209 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4210 Op == AtomicExpr::AO__atomic_store_n ||
4211 Op == AtomicExpr::AO__atomic_exchange_n ||
4212 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4213 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4214 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4215 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4216 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4220 enum ArithOpExtraValueType {
4225 unsigned ArithAllows = AOEVT_None;
4228 case AtomicExpr::AO__c11_atomic_init:
4229 case AtomicExpr::AO__opencl_atomic_init:
4233 case AtomicExpr::AO__c11_atomic_load:
4234 case AtomicExpr::AO__opencl_atomic_load:
4235 case AtomicExpr::AO__hip_atomic_load:
4236 case AtomicExpr::AO__atomic_load_n:
4237 case AtomicExpr::AO__scoped_atomic_load_n:
4241 case AtomicExpr::AO__atomic_load:
4242 case AtomicExpr::AO__scoped_atomic_load:
4246 case AtomicExpr::AO__c11_atomic_store:
4247 case AtomicExpr::AO__opencl_atomic_store:
4248 case AtomicExpr::AO__hip_atomic_store:
4249 case AtomicExpr::AO__atomic_store:
4250 case AtomicExpr::AO__atomic_store_n:
4251 case AtomicExpr::AO__scoped_atomic_store:
4252 case AtomicExpr::AO__scoped_atomic_store_n:
4255 case AtomicExpr::AO__atomic_fetch_add:
4256 case AtomicExpr::AO__atomic_fetch_sub:
4257 case AtomicExpr::AO__atomic_add_fetch:
4258 case AtomicExpr::AO__atomic_sub_fetch:
4259 case AtomicExpr::AO__scoped_atomic_fetch_add:
4260 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4261 case AtomicExpr::AO__scoped_atomic_add_fetch:
4262 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4263 case AtomicExpr::AO__c11_atomic_fetch_add:
4264 case AtomicExpr::AO__c11_atomic_fetch_sub:
4265 case AtomicExpr::AO__opencl_atomic_fetch_add:
4266 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4267 case AtomicExpr::AO__hip_atomic_fetch_add:
4268 case AtomicExpr::AO__hip_atomic_fetch_sub:
4269 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4272 case AtomicExpr::AO__atomic_fetch_max:
4273 case AtomicExpr::AO__atomic_fetch_min:
4274 case AtomicExpr::AO__atomic_max_fetch:
4275 case AtomicExpr::AO__atomic_min_fetch:
4276 case AtomicExpr::AO__scoped_atomic_fetch_max:
4277 case AtomicExpr::AO__scoped_atomic_fetch_min:
4278 case AtomicExpr::AO__scoped_atomic_max_fetch:
4279 case AtomicExpr::AO__scoped_atomic_min_fetch:
4280 case AtomicExpr::AO__c11_atomic_fetch_max:
4281 case AtomicExpr::AO__c11_atomic_fetch_min:
4282 case AtomicExpr::AO__opencl_atomic_fetch_max:
4283 case AtomicExpr::AO__opencl_atomic_fetch_min:
4284 case AtomicExpr::AO__hip_atomic_fetch_max:
4285 case AtomicExpr::AO__hip_atomic_fetch_min:
4286 ArithAllows = AOEVT_FP;
4289 case AtomicExpr::AO__c11_atomic_fetch_and:
4290 case AtomicExpr::AO__c11_atomic_fetch_or:
4291 case AtomicExpr::AO__c11_atomic_fetch_xor:
4292 case AtomicExpr::AO__hip_atomic_fetch_and:
4293 case AtomicExpr::AO__hip_atomic_fetch_or:
4294 case AtomicExpr::AO__hip_atomic_fetch_xor:
4295 case AtomicExpr::AO__c11_atomic_fetch_nand:
4296 case AtomicExpr::AO__opencl_atomic_fetch_and:
4297 case AtomicExpr::AO__opencl_atomic_fetch_or:
4298 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4299 case AtomicExpr::AO__atomic_fetch_and:
4300 case AtomicExpr::AO__atomic_fetch_or:
4301 case AtomicExpr::AO__atomic_fetch_xor:
4302 case AtomicExpr::AO__atomic_fetch_nand:
4303 case AtomicExpr::AO__atomic_and_fetch:
4304 case AtomicExpr::AO__atomic_or_fetch:
4305 case AtomicExpr::AO__atomic_xor_fetch:
4306 case AtomicExpr::AO__atomic_nand_fetch:
4307 case AtomicExpr::AO__scoped_atomic_fetch_and:
4308 case AtomicExpr::AO__scoped_atomic_fetch_or:
4309 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4310 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4311 case AtomicExpr::AO__scoped_atomic_and_fetch:
4312 case AtomicExpr::AO__scoped_atomic_or_fetch:
4313 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4314 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4318 case AtomicExpr::AO__c11_atomic_exchange:
4319 case AtomicExpr::AO__hip_atomic_exchange:
4320 case AtomicExpr::AO__opencl_atomic_exchange:
4321 case AtomicExpr::AO__atomic_exchange_n:
4322 case AtomicExpr::AO__scoped_atomic_exchange_n:
4326 case AtomicExpr::AO__atomic_exchange:
4327 case AtomicExpr::AO__scoped_atomic_exchange:
4331 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4332 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4333 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4334 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4335 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4336 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4340 case AtomicExpr::AO__atomic_compare_exchange:
4341 case AtomicExpr::AO__atomic_compare_exchange_n:
4342 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4343 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4347 case AtomicExpr::AO__atomic_test_and_set:
4348 Form = TestAndSetByte;
4351 case AtomicExpr::AO__atomic_clear:
4356 unsigned AdjustedNumArgs = NumArgs[Form];
4357 if ((IsOpenCL || IsHIP || IsScoped) &&
4358 Op != AtomicExpr::AO__opencl_atomic_init)
4361 if (Args.size() < AdjustedNumArgs) {
4362 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4363 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4366 }
else if (Args.size() > AdjustedNumArgs) {
4367 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4368 diag::err_typecheck_call_too_many_args)
4369 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4375 Expr *Ptr = Args[0];
4380 Ptr = ConvertedPtr.
get();
4383 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4393 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4399 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4405 }
else if (Form != Load && Form != LoadCopy) {
4407 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4413 if (Form != TestAndSetByte && Form != ClearByte) {
4416 diag::err_incomplete_type))
4419 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4420 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4430 pointerType->getPointeeType().getCVRQualifiers());
4440 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4449 auto IsAllowedValueType = [&](
QualType ValType,
4450 unsigned AllowedType) ->
bool {
4454 return AllowedType & AOEVT_Pointer;
4459 &
Context.getTargetInfo().getLongDoubleFormat() ==
4460 &llvm::APFloat::x87DoubleExtended())
4464 if (!IsAllowedValueType(ValType, ArithAllows)) {
4465 auto DID = ArithAllows & AOEVT_FP
4466 ? (ArithAllows & AOEVT_Pointer
4467 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4468 : diag::err_atomic_op_needs_atomic_int_or_fp)
4469 : diag::err_atomic_op_needs_atomic_int;
4476 diag::err_incomplete_type)) {
4482 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4493 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4509 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4521 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4524 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4530 bool IsPassedByAddress =
false;
4531 if (!IsC11 && !IsHIP && !IsN) {
4533 IsPassedByAddress =
true;
4538 APIOrderedArgs.push_back(Args[0]);
4542 APIOrderedArgs.push_back(Args[1]);
4548 APIOrderedArgs.push_back(Args[2]);
4549 APIOrderedArgs.push_back(Args[1]);
4552 APIOrderedArgs.push_back(Args[2]);
4553 APIOrderedArgs.push_back(Args[3]);
4554 APIOrderedArgs.push_back(Args[1]);
4557 APIOrderedArgs.push_back(Args[2]);
4558 APIOrderedArgs.push_back(Args[4]);
4559 APIOrderedArgs.push_back(Args[1]);
4560 APIOrderedArgs.push_back(Args[3]);
4563 APIOrderedArgs.push_back(Args[2]);
4564 APIOrderedArgs.push_back(Args[4]);
4565 APIOrderedArgs.push_back(Args[5]);
4566 APIOrderedArgs.push_back(Args[1]);
4567 APIOrderedArgs.push_back(Args[3]);
4569 case TestAndSetByte:
4571 APIOrderedArgs.push_back(Args[1]);
4575 APIOrderedArgs.append(Args.begin(), Args.end());
4582 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4584 if (i < NumVals[Form] + 1) {
4597 assert(Form != Load);
4599 Ty =
Context.getPointerDiffType();
4602 else if (Form ==
Copy || Form == Xchg) {
4603 if (IsPassedByAddress) {
4610 Expr *ValArg = APIOrderedArgs[i];
4617 AS = PtrTy->getPointeeType().getAddressSpace();
4626 if (IsPassedByAddress)
4646 APIOrderedArgs[i] = Arg.
get();
4651 SubExprs.push_back(Ptr);
4655 SubExprs.push_back(APIOrderedArgs[1]);
4658 case TestAndSetByte:
4660 SubExprs.push_back(APIOrderedArgs[1]);
4666 SubExprs.push_back(APIOrderedArgs[2]);
4667 SubExprs.push_back(APIOrderedArgs[1]);
4671 SubExprs.push_back(APIOrderedArgs[3]);
4672 SubExprs.push_back(APIOrderedArgs[1]);
4673 SubExprs.push_back(APIOrderedArgs[2]);
4676 SubExprs.push_back(APIOrderedArgs[3]);
4677 SubExprs.push_back(APIOrderedArgs[1]);
4678 SubExprs.push_back(APIOrderedArgs[4]);
4679 SubExprs.push_back(APIOrderedArgs[2]);
4682 SubExprs.push_back(APIOrderedArgs[4]);
4683 SubExprs.push_back(APIOrderedArgs[1]);
4684 SubExprs.push_back(APIOrderedArgs[5]);
4685 SubExprs.push_back(APIOrderedArgs[2]);
4686 SubExprs.push_back(APIOrderedArgs[3]);
4691 if (SubExprs.size() >= 2 && Form !=
Init) {
4692 std::optional<llvm::APSInt>
Success =
4693 SubExprs[1]->getIntegerConstantExpr(
Context);
4695 Diag(SubExprs[1]->getBeginLoc(),
4696 diag::warn_atomic_op_has_invalid_memory_order)
4697 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4698 << SubExprs[1]->getSourceRange();
4700 if (SubExprs.size() >= 5) {
4701 if (std::optional<llvm::APSInt> Failure =
4702 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4703 if (!llvm::is_contained(
4704 {llvm::AtomicOrderingCABI::relaxed,
4705 llvm::AtomicOrderingCABI::consume,
4706 llvm::AtomicOrderingCABI::acquire,
4707 llvm::AtomicOrderingCABI::seq_cst},
4708 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4709 Diag(SubExprs[3]->getBeginLoc(),
4710 diag::warn_atomic_op_has_invalid_memory_order)
4711 << 2 << SubExprs[3]->getSourceRange();
4718 auto *
Scope = Args[Args.size() - 1];
4719 if (std::optional<llvm::APSInt>
Result =
4721 if (!ScopeModel->isValid(
Result->getZExtValue()))
4722 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4723 <<
Scope->getSourceRange();
4725 SubExprs.push_back(
Scope);
4731 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4732 Op == AtomicExpr::AO__c11_atomic_store ||
4733 Op == AtomicExpr::AO__opencl_atomic_load ||
4734 Op == AtomicExpr::AO__hip_atomic_load ||
4735 Op == AtomicExpr::AO__opencl_atomic_store ||
4736 Op == AtomicExpr::AO__hip_atomic_store) &&
4737 Context.AtomicUsesUnsupportedLibcall(AE))
4739 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4740 Op == AtomicExpr::AO__opencl_atomic_load ||
4741 Op == AtomicExpr::AO__hip_atomic_load)
4746 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4762 assert(Fn &&
"builtin call without direct callee!");
4778 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4785 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4787 <<
Callee->getSourceRange();
4796 Expr *FirstArg = TheCall->
getArg(0);
4800 FirstArg = FirstArgResult.
get();
4801 TheCall->
setArg(0, FirstArg);
4813 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4820 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4850 QualType ResultType = ValType;
4855#define BUILTIN_ROW(x) \
4856 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4857 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4859 static const unsigned BuiltinIndices[][5] = {
4884 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
4885 case 1: SizeIndex = 0;
break;
4886 case 2: SizeIndex = 1;
break;
4887 case 4: SizeIndex = 2;
break;
4888 case 8: SizeIndex = 3;
break;
4889 case 16: SizeIndex = 4;
break;
4901 unsigned BuiltinIndex, NumFixed = 1;
4902 bool WarnAboutSemanticsChange =
false;
4903 switch (BuiltinID) {
4904 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4905 case Builtin::BI__sync_fetch_and_add:
4906 case Builtin::BI__sync_fetch_and_add_1:
4907 case Builtin::BI__sync_fetch_and_add_2:
4908 case Builtin::BI__sync_fetch_and_add_4:
4909 case Builtin::BI__sync_fetch_and_add_8:
4910 case Builtin::BI__sync_fetch_and_add_16:
4914 case Builtin::BI__sync_fetch_and_sub:
4915 case Builtin::BI__sync_fetch_and_sub_1:
4916 case Builtin::BI__sync_fetch_and_sub_2:
4917 case Builtin::BI__sync_fetch_and_sub_4:
4918 case Builtin::BI__sync_fetch_and_sub_8:
4919 case Builtin::BI__sync_fetch_and_sub_16:
4923 case Builtin::BI__sync_fetch_and_or:
4924 case Builtin::BI__sync_fetch_and_or_1:
4925 case Builtin::BI__sync_fetch_and_or_2:
4926 case Builtin::BI__sync_fetch_and_or_4:
4927 case Builtin::BI__sync_fetch_and_or_8:
4928 case Builtin::BI__sync_fetch_and_or_16:
4932 case Builtin::BI__sync_fetch_and_and:
4933 case Builtin::BI__sync_fetch_and_and_1:
4934 case Builtin::BI__sync_fetch_and_and_2:
4935 case Builtin::BI__sync_fetch_and_and_4:
4936 case Builtin::BI__sync_fetch_and_and_8:
4937 case Builtin::BI__sync_fetch_and_and_16:
4941 case Builtin::BI__sync_fetch_and_xor:
4942 case Builtin::BI__sync_fetch_and_xor_1:
4943 case Builtin::BI__sync_fetch_and_xor_2:
4944 case Builtin::BI__sync_fetch_and_xor_4:
4945 case Builtin::BI__sync_fetch_and_xor_8:
4946 case Builtin::BI__sync_fetch_and_xor_16:
4950 case Builtin::BI__sync_fetch_and_nand:
4951 case Builtin::BI__sync_fetch_and_nand_1:
4952 case Builtin::BI__sync_fetch_and_nand_2:
4953 case Builtin::BI__sync_fetch_and_nand_4:
4954 case Builtin::BI__sync_fetch_and_nand_8:
4955 case Builtin::BI__sync_fetch_and_nand_16:
4957 WarnAboutSemanticsChange =
true;
4960 case Builtin::BI__sync_add_and_fetch:
4961 case Builtin::BI__sync_add_and_fetch_1:
4962 case Builtin::BI__sync_add_and_fetch_2:
4963 case Builtin::BI__sync_add_and_fetch_4:
4964 case Builtin::BI__sync_add_and_fetch_8:
4965 case Builtin::BI__sync_add_and_fetch_16:
4969 case Builtin::BI__sync_sub_and_fetch:
4970 case Builtin::BI__sync_sub_and_fetch_1:
4971 case Builtin::BI__sync_sub_and_fetch_2:
4972 case Builtin::BI__sync_sub_and_fetch_4:
4973 case Builtin::BI__sync_sub_and_fetch_8:
4974 case Builtin::BI__sync_sub_and_fetch_16:
4978 case Builtin::BI__sync_and_and_fetch:
4979 case Builtin::BI__sync_and_and_fetch_1:
4980 case Builtin::BI__sync_and_and_fetch_2:
4981 case Builtin::BI__sync_and_and_fetch_4:
4982 case Builtin::BI__sync_and_and_fetch_8:
4983 case Builtin::BI__sync_and_and_fetch_16:
4987 case Builtin::BI__sync_or_and_fetch:
4988 case Builtin::BI__sync_or_and_fetch_1:
4989 case Builtin::BI__sync_or_and_fetch_2:
4990 case Builtin::BI__sync_or_and_fetch_4:
4991 case Builtin::BI__sync_or_and_fetch_8:
4992 case Builtin::BI__sync_or_and_fetch_16:
4996 case Builtin::BI__sync_xor_and_fetch:
4997 case Builtin::BI__sync_xor_and_fetch_1:
4998 case Builtin::BI__sync_xor_and_fetch_2:
4999 case Builtin::BI__sync_xor_and_fetch_4:
5000 case Builtin::BI__sync_xor_and_fetch_8:
5001 case Builtin::BI__sync_xor_and_fetch_16:
5005 case Builtin::BI__sync_nand_and_fetch:
5006 case Builtin::BI__sync_nand_and_fetch_1:
5007 case Builtin::BI__sync_nand_and_fetch_2:
5008 case Builtin::BI__sync_nand_and_fetch_4:
5009 case Builtin::BI__sync_nand_and_fetch_8:
5010 case Builtin::BI__sync_nand_and_fetch_16:
5012 WarnAboutSemanticsChange =
true;
5015 case Builtin::BI__sync_val_compare_and_swap:
5016 case Builtin::BI__sync_val_compare_and_swap_1:
5017 case Builtin::BI__sync_val_compare_and_swap_2:
5018 case Builtin::BI__sync_val_compare_and_swap_4:
5019 case Builtin::BI__sync_val_compare_and_swap_8:
5020 case Builtin::BI__sync_val_compare_and_swap_16:
5025 case Builtin::BI__sync_bool_compare_and_swap:
5026 case Builtin::BI__sync_bool_compare_and_swap_1:
5027 case Builtin::BI__sync_bool_compare_and_swap_2:
5028 case Builtin::BI__sync_bool_compare_and_swap_4:
5029 case Builtin::BI__sync_bool_compare_and_swap_8:
5030 case Builtin::BI__sync_bool_compare_and_swap_16:
5036 case Builtin::BI__sync_lock_test_and_set:
5037 case Builtin::BI__sync_lock_test_and_set_1:
5038 case Builtin::BI__sync_lock_test_and_set_2:
5039 case Builtin::BI__sync_lock_test_and_set_4:
5040 case Builtin::BI__sync_lock_test_and_set_8:
5041 case Builtin::BI__sync_lock_test_and_set_16:
5045 case Builtin::BI__sync_lock_release:
5046 case Builtin::BI__sync_lock_release_1:
5047 case Builtin::BI__sync_lock_release_2:
5048 case Builtin::BI__sync_lock_release_4:
5049 case Builtin::BI__sync_lock_release_8:
5050 case Builtin::BI__sync_lock_release_16:
5056 case Builtin::BI__sync_swap:
5057 case Builtin::BI__sync_swap_1:
5058 case Builtin::BI__sync_swap_2:
5059 case Builtin::BI__sync_swap_4:
5060 case Builtin::BI__sync_swap_8:
5061 case Builtin::BI__sync_swap_16:
5069 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5070 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5071 <<
Callee->getSourceRange();
5075 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5076 <<
Callee->getSourceRange();
5078 if (WarnAboutSemanticsChange) {
5079 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5080 <<
Callee->getSourceRange();
5085 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5086 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5087 FunctionDecl *NewBuiltinDecl;
5088 if (NewBuiltinID == BuiltinID)
5089 NewBuiltinDecl = FDecl;
5092 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5095 assert(Res.getFoundDecl());
5096 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5097 if (!NewBuiltinDecl)
5104 for (
unsigned i = 0; i != NumFixed; ++i) {
5133 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5135 CK_BuiltinFnToFnPtr);
5146 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5147 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5148 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5152 return TheCallResult;
5156 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5161 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5162 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5163 "Unexpected nontemporal load/store builtin!");
5164 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5165 unsigned numArgs = isStore ? 2 : 1;
5175 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5181 PointerArg = PointerArgResult.
get();
5182 TheCall->
setArg(numArgs - 1, PointerArg);
5186 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5199 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5206 return TheCallResult;
5218 return TheCallResult;
5225 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5227 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5228 Literal = ObjcLiteral->getString();
5232 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5239 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5240 InitializedEntity Entity =
5250 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5251 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5252 TT.getArch() == llvm::Triple::aarch64_32);
5253 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5254 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5255 if (IsX64 || IsAArch64) {
5262 return S.
Diag(Fn->getBeginLoc(),
5263 diag::err_ms_va_start_used_in_sysv_function);
5270 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5271 return S.
Diag(Fn->getBeginLoc(),
5272 diag::err_va_start_used_in_wrong_abi_function)
5273 << !IsWindowsOrUEFI;
5279 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5287 bool IsVariadic =
false;
5290 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5291 IsVariadic =
Block->isVariadic();
5292 Params =
Block->parameters();
5293 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5296 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5297 IsVariadic = MD->isVariadic();
5299 Params = MD->parameters();
5302 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5306 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5311 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5316 *LastParam = Params.empty() ?
nullptr : Params.back();
5321bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5326 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5350 ParmVarDecl *LastParam;
5361 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5363 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5368 if (std::optional<llvm::APSInt> Val =
5370 Val &&
LangOpts.C23 && *Val == 0 &&
5371 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5372 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5379 SourceLocation ParamLoc;
5380 bool IsCRegister =
false;
5381 bool SecondArgIsLastNonVariadicArgument =
false;
5382 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5383 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5384 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5387 ParamLoc = PV->getLocation();
5393 if (!SecondArgIsLastNonVariadicArgument)
5395 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5396 else if (IsCRegister ||
Type->isReferenceType() ||
5397 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5400 if (!Context.isPromotableIntegerType(Type))
5402 const auto *ED = Type->getAsEnumDecl();
5405 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5407 unsigned Reason = 0;
5408 if (
Type->isReferenceType()) Reason = 1;
5409 else if (IsCRegister) Reason = 2;
5410 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5411 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5418 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5438 if (
Call->getNumArgs() < 3)
5440 diag::err_typecheck_call_too_few_args_at_least)
5441 << 0 << 3 <<
Call->getNumArgs()
5454 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5457 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5460 const QualType &ConstCharPtrTy =
5462 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5464 << Arg1->
getType() << ConstCharPtrTy << 1
5467 << 2 << Arg1->
getType() << ConstCharPtrTy;
5469 const QualType SizeTy =
Context.getSizeType();
5474 << Arg2->
getType() << SizeTy << 1
5477 << 3 << Arg2->
getType() << SizeTy;
5482bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5486 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5514 diag::err_typecheck_call_invalid_ordered_compare)
5522bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5523 unsigned BuiltinID) {
5528 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5529 BuiltinID == Builtin::BI__builtin_isinf ||
5530 BuiltinID == Builtin::BI__builtin_isinf_sign))
5534 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5535 BuiltinID == Builtin::BI__builtin_isunordered))
5539 bool IsFPClass = NumArgs == 2;
5542 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5546 for (
unsigned i = 0; i < FPArgNo; ++i) {
5547 Expr *Arg = TheCall->
getArg(i);
5560 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5568 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5573 OrigArg = Res.
get();
5579 OrigArg = Res.
get();
5581 TheCall->
setArg(FPArgNo, OrigArg);
5583 QualType VectorResultTy;
5584 QualType ElementTy = OrigArg->
getType();
5589 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5595 diag::err_typecheck_call_invalid_unary_fp)
5607 if (!VectorResultTy.
isNull())
5608 ResultTy = VectorResultTy;
5617bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5622 for (
unsigned I = 0; I != 2; ++I) {
5623 Expr *Arg = TheCall->
getArg(I);
5633 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5648 Expr *Real = TheCall->
getArg(0);
5649 Expr *Imag = TheCall->
getArg(1);
5652 diag::err_typecheck_call_different_arg_types)
5667 diag::err_typecheck_call_too_few_args_at_least)
5668 << 0 << 2 << NumArgs
5675 unsigned NumElements = 0;
5690 unsigned NumResElements = NumArgs - 2;
5699 diag::err_vec_builtin_incompatible_vector)
5704 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5706 diag::err_vec_builtin_incompatible_vector)
5711 }
else if (NumElements != NumResElements) {
5714 ?
Context.getExtVectorType(EltType, NumResElements)
5715 :
Context.getVectorType(EltType, NumResElements,
5720 for (
unsigned I = 2; I != NumArgs; ++I) {
5728 diag::err_shufflevector_nonconstant_argument)
5734 else if (
Result->getActiveBits() > 64 ||
5735 Result->getZExtValue() >= NumElements * 2)
5737 diag::err_shufflevector_argument_too_large)
5762 diag::err_convertvector_non_vector)
5765 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5767 <<
"__builtin_convertvector");
5772 if (SrcElts != DstElts)
5774 diag::err_convertvector_incompatible_vector)
5782bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5787 diag::err_typecheck_call_too_many_args_at_most)
5788 << 0 << 3 << NumArgs << 0
5793 for (
unsigned i = 1; i != NumArgs; ++i)
5800bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5801 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5802 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5812 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5822bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5823 Expr *Arg = TheCall->
getArg(0);
5834bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5836 Expr *Arg = TheCall->
getArg(1);
5840 if (
const auto *UE =
5842 if (UE->getKind() == UETT_AlignOf ||
5843 UE->getKind() == UETT_PreferredAlignOf)
5849 if (!
Result.isPowerOf2())
5850 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5857 if (
Result > std::numeric_limits<int32_t>::max())
5865bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5870 Expr *FirstArg = TheCall->
getArg(0);
5876 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5880 TheCall->
setArg(0, FirstArgResult.
get());
5884 Expr *SecondArg = TheCall->
getArg(1);
5892 if (!
Result.isPowerOf2())
5893 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5902 Expr *ThirdArg = TheCall->
getArg(2);
5905 TheCall->
setArg(2, ThirdArg);
5911bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5912 unsigned BuiltinID =
5914 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5917 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5918 if (NumArgs < NumRequiredArgs) {
5919 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5920 << 0 << NumRequiredArgs << NumArgs
5923 if (NumArgs >= NumRequiredArgs + 0x100) {
5925 diag::err_typecheck_call_too_many_args_at_most)
5926 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5937 if (Arg.isInvalid())
5939 TheCall->
setArg(i, Arg.get());
5944 unsigned FormatIdx = i;
5954 unsigned FirstDataArg = i;
5955 while (i < NumArgs) {
5973 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5975 bool Success = CheckFormatArguments(
5978 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6002 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6011 int High,
bool RangeIsError) {
6025 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6033 PDiag(diag::warn_argument_invalid_range)
6076 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6081 if (
Value.isNegative())
6092 if ((
Value & 0xFF) != 0)
6117 Result.setIsUnsigned(
true);
6122 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6142 Result.setIsUnsigned(
true);
6150 diag::err_argument_not_shifted_byte_or_xxff)
6154bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6155 if (!Context.getTargetInfo().hasSjLjLowering())
6156 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6167 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6173bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6174 if (!Context.getTargetInfo().hasSjLjLowering())
6175 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6180bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6195 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6200 diag::err_builtin_counted_by_ref_has_side_effects)
6203 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6204 if (!ME->isFlexibleArrayMemberLike(
6207 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6211 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6214 if (
const FieldDecl *CountFD = FAMDecl->findCountedByField()) {
6221 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6231bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6233 const CallExpr *CE =
6242 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6247 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6252 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6256 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6260 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6270class UncoveredArgHandler {
6271 enum {
Unknown = -1, AllCovered = -2 };
6273 signed FirstUncoveredArg =
Unknown;
6274 SmallVector<const Expr *, 4> DiagnosticExprs;
6277 UncoveredArgHandler() =
default;
6279 bool hasUncoveredArg()
const {
6280 return (FirstUncoveredArg >= 0);
6283 unsigned getUncoveredArg()
const {
6284 assert(hasUncoveredArg() &&
"no uncovered argument");
6285 return FirstUncoveredArg;
6288 void setAllCovered() {
6291 DiagnosticExprs.clear();
6292 FirstUncoveredArg = AllCovered;
6295 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6296 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6299 if (FirstUncoveredArg == AllCovered)
6304 if (NewFirstUncoveredArg == FirstUncoveredArg)
6305 DiagnosticExprs.push_back(StrExpr);
6306 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6307 DiagnosticExprs.clear();
6308 DiagnosticExprs.push_back(StrExpr);
6309 FirstUncoveredArg = NewFirstUncoveredArg;
6313 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6316enum StringLiteralCheckType {
6318 SLCT_UncheckedLiteral,
6326 bool AddendIsRight) {
6327 unsigned BitWidth = Offset.getBitWidth();
6328 unsigned AddendBitWidth = Addend.getBitWidth();
6330 if (Addend.isUnsigned()) {
6331 Addend = Addend.zext(++AddendBitWidth);
6332 Addend.setIsSigned(
true);
6335 if (AddendBitWidth > BitWidth) {
6336 Offset = Offset.sext(AddendBitWidth);
6337 BitWidth = AddendBitWidth;
6338 }
else if (BitWidth > AddendBitWidth) {
6339 Addend = Addend.sext(BitWidth);
6343 llvm::APSInt ResOffset = Offset;
6344 if (BinOpKind == BO_Add)
6345 ResOffset = Offset.sadd_ov(Addend, Ov);
6347 assert(AddendIsRight && BinOpKind == BO_Sub &&
6348 "operator must be add or sub with addend on the right");
6349 ResOffset = Offset.ssub_ov(Addend, Ov);
6355 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6356 "index (intermediate) result too big");
6357 Offset = Offset.sext(2 * BitWidth);
6358 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6370class FormatStringLiteral {
6371 const StringLiteral *FExpr;
6375 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6376 : FExpr(fexpr), Offset(Offset) {}
6378 const StringLiteral *getFormatString()
const {
return FExpr; }
6380 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6382 unsigned getByteLength()
const {
6383 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6386 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6393 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6394 bool isWide()
const {
return FExpr->
isWide(); }
6395 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6396 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6397 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6398 bool isPascal()
const {
return FExpr->
isPascal(); }
6400 SourceLocation getLocationOfByte(
6401 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6402 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6403 unsigned *StartTokenByteOffset =
nullptr)
const {
6405 StartToken, StartTokenByteOffset);
6408 SourceLocation getBeginLoc() const LLVM_READONLY {
6412 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6418 Sema &S,
const FormatStringLiteral *FExpr,
6423 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6424 bool IgnoreStringsWithoutSpecifiers);
6438 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6439 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6441 return SLCT_NotALiteral;
6443 assert(Offset.isSigned() &&
"invalid offset");
6446 return SLCT_NotALiteral;
6455 return SLCT_UncheckedLiteral;
6458 case Stmt::InitListExprClass:
6462 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6463 Type, CallType,
false, CheckedVarArgs,
6464 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6466 return SLCT_NotALiteral;
6467 case Stmt::BinaryConditionalOperatorClass:
6468 case Stmt::ConditionalOperatorClass: {
6477 bool CheckLeft =
true, CheckRight =
true;
6480 if (
C->getCond()->EvaluateAsBooleanCondition(
6492 StringLiteralCheckType Left;
6494 Left = SLCT_UncheckedLiteral;
6497 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6498 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6499 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6500 if (Left == SLCT_NotALiteral || !CheckRight) {
6506 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6507 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6508 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6510 return (CheckLeft && Left < Right) ? Left : Right;
6513 case Stmt::ImplicitCastExprClass:
6517 case Stmt::OpaqueValueExprClass:
6522 return SLCT_NotALiteral;
6524 case Stmt::PredefinedExprClass:
6528 return SLCT_UncheckedLiteral;
6530 case Stmt::DeclRefExprClass: {
6536 bool isConstant =
false;
6540 isConstant = AT->getElementType().isConstant(S.
Context);
6542 isConstant =
T.isConstant(S.
Context) &&
6543 PT->getPointeeType().isConstant(S.
Context);
6544 }
else if (
T->isObjCObjectPointerType()) {
6547 isConstant =
T.isConstant(S.
Context);
6551 if (
const Expr *
Init = VD->getAnyInitializer()) {
6554 if (InitList->isStringLiteralInit())
6555 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6558 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6559 firstDataArg,
Type, CallType,
6560 false, CheckedVarArgs, UncoveredArg, Offset);
6611 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6612 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6613 for (
const auto *PVFormatMatches :
6614 D->specific_attrs<FormatMatchesAttr>()) {
6619 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6623 S.
Diag(Args[format_idx]->getBeginLoc(),
6624 diag::warn_format_string_type_incompatible)
6625 << PVFormatMatches->getType()->getName()
6627 if (!InFunctionCall) {
6628 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6629 diag::note_format_string_defined);
6631 return SLCT_UncheckedLiteral;
6634 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6635 Args, APK, format_idx, firstDataArg,
Type, CallType,
6636 false, CheckedVarArgs, UncoveredArg,
6637 Offset, IgnoreStringsWithoutSpecifiers);
6641 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6644 PVFormat->getFirstArg(), &CallerFSI))
6646 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6650 S.
Diag(Args[format_idx]->getBeginLoc(),
6651 diag::warn_format_string_type_incompatible)
6652 << PVFormat->getType()->getName()
6654 if (!InFunctionCall) {
6657 return SLCT_UncheckedLiteral;
6670 return SLCT_UncheckedLiteral;
6678 return SLCT_NotALiteral;
6681 case Stmt::CallExprClass:
6682 case Stmt::CXXMemberCallExprClass: {
6686 StringLiteralCheckType CommonResult;
6687 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6688 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6690 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6691 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6692 Offset, IgnoreStringsWithoutSpecifiers);
6694 CommonResult = Result;
6699 return CommonResult;
6701 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6703 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6704 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6707 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6708 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6709 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6715 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6716 Type, CallType,
false, CheckedVarArgs,
6717 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6718 return SLCT_NotALiteral;
6720 case Stmt::ObjCMessageExprClass: {
6722 if (
const auto *MD = ME->getMethodDecl()) {
6723 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6732 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6734 MD->getSelector().isKeywordSelector(
6735 {
"localizedStringForKey",
"value",
"table"})) {
6736 IgnoreStringsWithoutSpecifiers =
true;
6739 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6741 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6742 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6743 Offset, IgnoreStringsWithoutSpecifiers);
6747 return SLCT_NotALiteral;
6749 case Stmt::ObjCStringLiteralClass:
6750 case Stmt::StringLiteralClass: {
6759 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6762 return SLCT_NotALiteral;
6764 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6766 format_idx, firstDataArg,
Type, InFunctionCall,
6767 CallType, CheckedVarArgs, UncoveredArg,
6768 IgnoreStringsWithoutSpecifiers);
6769 return SLCT_CheckedLiteral;
6772 return SLCT_NotALiteral;
6774 case Stmt::BinaryOperatorClass: {
6788 if (LIsInt != RIsInt) {
6792 if (BinOpKind == BO_Add) {
6805 return SLCT_NotALiteral;
6807 case Stmt::UnaryOperatorClass: {
6809 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6810 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6812 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6822 return SLCT_NotALiteral;
6826 return SLCT_NotALiteral;
6837 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6838 if (isa_and_nonnull<StringLiteral>(LVE))
6859 return "freebsd_kprintf";
6868 return llvm::StringSwitch<FormatStringType>(Flavor)
6870 .Cases(
"gnu_printf",
"printf",
"printf0",
"syslog",
6875 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
6891bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6895 llvm::SmallBitVector &CheckedVarArgs) {
6896 FormatStringInfo FSI;
6900 return CheckFormatArguments(
6901 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
6906bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
6910 llvm::SmallBitVector &CheckedVarArgs) {
6911 FormatStringInfo FSI;
6915 return CheckFormatArguments(Args, FSI.ArgPassingKind,
6916 Format->getFormatString(), FSI.FormatIdx,
6918 CallType, Loc, Range, CheckedVarArgs);
6926 unsigned format_idx,
unsigned firstDataArg,
6930 llvm::SmallBitVector &CheckedVarArgs) {
6932 if (format_idx >= Args.size()) {
6933 Diag(Loc, diag::warn_missing_format_string) <<
Range;
6937 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6951 UncoveredArgHandler UncoveredArg;
6953 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
6954 firstDataArg,
Type, CallType,
6955 true, CheckedVarArgs, UncoveredArg,
6956 llvm::APSInt(64,
false) = 0);
6959 if (UncoveredArg.hasUncoveredArg()) {
6960 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6961 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6962 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6965 if (CT != SLCT_NotALiteral)
6967 return CT == SLCT_CheckedLiteral;
6978 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
6985 if (Args.size() == firstDataArg) {
6986 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6994 Diag(FormatLoc, diag::note_format_security_fixit)
6998 Diag(FormatLoc, diag::note_format_security_fixit)
7003 Diag(FormatLoc, diag::warn_format_nonliteral)
7014 const FormatStringLiteral *FExpr;
7015 const Expr *OrigFormatExpr;
7017 const unsigned FirstDataArg;
7018 const unsigned NumDataArgs;
7021 ArrayRef<const Expr *> Args;
7023 llvm::SmallBitVector CoveredArgs;
7024 bool usesPositionalArgs =
false;
7025 bool atFirstArg =
true;
7026 bool inFunctionCall;
7028 llvm::SmallBitVector &CheckedVarArgs;
7029 UncoveredArgHandler &UncoveredArg;
7032 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7034 unsigned firstDataArg,
unsigned numDataArgs,
7036 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7038 llvm::SmallBitVector &CheckedVarArgs,
7039 UncoveredArgHandler &UncoveredArg)
7040 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7041 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7042 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7043 inFunctionCall(inFunctionCall), CallType(callType),
7044 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7045 CoveredArgs.resize(numDataArgs);
7046 CoveredArgs.reset();
7049 bool HasFormatArguments()
const {
7054 void DoneProcessing();
7056 void HandleIncompleteSpecifier(
const char *startSpecifier,
7057 unsigned specifierLen)
override;
7059 void HandleInvalidLengthModifier(
7060 const analyze_format_string::FormatSpecifier &FS,
7061 const analyze_format_string::ConversionSpecifier &CS,
7062 const char *startSpecifier,
unsigned specifierLen,
7065 void HandleNonStandardLengthModifier(
7066 const analyze_format_string::FormatSpecifier &FS,
7067 const char *startSpecifier,
unsigned specifierLen);
7069 void HandleNonStandardConversionSpecifier(
7070 const analyze_format_string::ConversionSpecifier &CS,
7071 const char *startSpecifier,
unsigned specifierLen);
7073 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7075 void HandleInvalidPosition(
const char *startSpecifier,
7076 unsigned specifierLen,
7079 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7081 void HandleNullChar(
const char *nullCharacter)
override;
7083 template <
typename Range>
7085 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7086 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7087 bool IsStringLocation, Range StringRange,
7088 ArrayRef<FixItHint> Fixit = {});
7091 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7092 const char *startSpec,
7093 unsigned specifierLen,
7094 const char *csStart,
unsigned csLen);
7096 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7097 const char *startSpec,
7098 unsigned specifierLen);
7100 SourceRange getFormatStringRange();
7101 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7102 unsigned specifierLen);
7103 SourceLocation getLocationOfByte(
const char *x);
7105 const Expr *getDataArg(
unsigned i)
const;
7107 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7108 const analyze_format_string::ConversionSpecifier &CS,
7109 const char *startSpecifier,
unsigned specifierLen,
7112 template <
typename Range>
7113 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7114 bool IsStringLocation, Range StringRange,
7115 ArrayRef<FixItHint> Fixit = {});
7120SourceRange CheckFormatHandler::getFormatStringRange() {
7125getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7127 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7135SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7140void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7141 unsigned specifierLen){
7142 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7143 getLocationOfByte(startSpecifier),
7145 getSpecifierRange(startSpecifier, specifierLen));
7148void CheckFormatHandler::HandleInvalidLengthModifier(
7151 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7163 getSpecifierRange(startSpecifier, specifierLen));
7165 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7166 << FixedLM->toString()
7171 if (DiagID == diag::warn_format_nonsensical_length)
7177 getSpecifierRange(startSpecifier, specifierLen),
7182void CheckFormatHandler::HandleNonStandardLengthModifier(
7184 const char *startSpecifier,
unsigned specifierLen) {
7193 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7197 getSpecifierRange(startSpecifier, specifierLen));
7199 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7200 << FixedLM->toString()
7204 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7208 getSpecifierRange(startSpecifier, specifierLen));
7212void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7214 const char *startSpecifier,
unsigned specifierLen) {
7220 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7224 getSpecifierRange(startSpecifier, specifierLen));
7227 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7228 << FixedCS->toString()
7231 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7235 getSpecifierRange(startSpecifier, specifierLen));
7239void CheckFormatHandler::HandlePosition(
const char *startPos,
7242 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7243 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7244 getLocationOfByte(startPos),
7246 getSpecifierRange(startPos, posLen));
7249void CheckFormatHandler::HandleInvalidPosition(
7250 const char *startSpecifier,
unsigned specifierLen,
7253 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7254 EmitFormatDiagnostic(
7255 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7256 getLocationOfByte(startSpecifier),
true,
7257 getSpecifierRange(startSpecifier, specifierLen));
7260void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7264 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7265 getLocationOfByte(startPos),
7267 getSpecifierRange(startPos, posLen));
7270void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7273 EmitFormatDiagnostic(
7274 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7275 getLocationOfByte(nullCharacter),
true,
7276 getFormatStringRange());
7282const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7283 return Args[FirstDataArg + i];
7286void CheckFormatHandler::DoneProcessing() {
7289 if (HasFormatArguments()) {
7292 signed notCoveredArg = CoveredArgs.find_first();
7293 if (notCoveredArg >= 0) {
7294 assert((
unsigned)notCoveredArg < NumDataArgs);
7295 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7297 UncoveredArg.setAllCovered();
7302void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7303 const Expr *ArgExpr) {
7304 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7316 for (
auto E : DiagnosticExprs)
7319 CheckFormatHandler::EmitFormatDiagnostic(
7320 S, IsFunctionCall, DiagnosticExprs[0],
7326CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7328 const char *startSpec,
7329 unsigned specifierLen,
7330 const char *csStart,
7332 bool keepGoing =
true;
7333 if (argIndex < NumDataArgs) {
7336 CoveredArgs.set(argIndex);
7352 std::string CodePointStr;
7353 if (!llvm::sys::locale::isPrint(*csStart)) {
7354 llvm::UTF32 CodePoint;
7355 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7356 const llvm::UTF8 *E =
7357 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7358 llvm::ConversionResult
Result =
7359 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7361 if (
Result != llvm::conversionOK) {
7362 unsigned char FirstChar = *csStart;
7363 CodePoint = (llvm::UTF32)FirstChar;
7366 llvm::raw_string_ostream
OS(CodePointStr);
7367 if (CodePoint < 256)
7368 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7369 else if (CodePoint <= 0xFFFF)
7370 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7372 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7376 EmitFormatDiagnostic(
7377 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7378 true, getSpecifierRange(startSpec, specifierLen));
7384CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7385 const char *startSpec,
7386 unsigned specifierLen) {
7387 EmitFormatDiagnostic(
7388 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7389 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7393CheckFormatHandler::CheckNumArgs(
7396 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7398 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7400 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7401 << (argIndex+1) << NumDataArgs)
7402 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7403 EmitFormatDiagnostic(
7404 PDiag, getLocationOfByte(CS.
getStart()),
true,
7405 getSpecifierRange(startSpecifier, specifierLen));
7409 UncoveredArg.setAllCovered();
7415template<
typename Range>
7418 bool IsStringLocation,
7421 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7422 Loc, IsStringLocation, StringRange, FixIt);
7452template <
typename Range>
7453void CheckFormatHandler::EmitFormatDiagnostic(
7454 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7457 if (InFunctionCall) {
7462 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7466 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7467 diag::note_format_string_defined);
7469 Note << StringRange;
7478class CheckPrintfHandler :
public CheckFormatHandler {
7480 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7482 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7484 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7486 llvm::SmallBitVector &CheckedVarArgs,
7487 UncoveredArgHandler &UncoveredArg)
7488 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7489 numDataArgs, beg, APK, Args, formatIdx,
7490 inFunctionCall, CallType, CheckedVarArgs,
7493 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7496 bool allowsObjCArg()
const {
7497 return FSType == FormatStringType::NSString ||
7498 FSType == FormatStringType::OSLog ||
7499 FSType == FormatStringType::OSTrace;
7502 bool HandleInvalidPrintfConversionSpecifier(
7503 const analyze_printf::PrintfSpecifier &FS,
7504 const char *startSpecifier,
7505 unsigned specifierLen)
override;
7507 void handleInvalidMaskType(StringRef MaskType)
override;
7509 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7510 const char *startSpecifier,
unsigned specifierLen,
7511 const TargetInfo &
Target)
override;
7512 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7513 const char *StartSpecifier,
7514 unsigned SpecifierLen,
7517 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7518 const char *startSpecifier,
unsigned specifierLen);
7519 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7520 const analyze_printf::OptionalAmount &Amt,
7522 const char *startSpecifier,
unsigned specifierLen);
7523 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7524 const analyze_printf::OptionalFlag &flag,
7525 const char *startSpecifier,
unsigned specifierLen);
7526 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7527 const analyze_printf::OptionalFlag &ignoredFlag,
7528 const analyze_printf::OptionalFlag &flag,
7529 const char *startSpecifier,
unsigned specifierLen);
7530 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7533 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7534 unsigned flagLen)
override;
7536 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7537 unsigned flagLen)
override;
7540 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7541 const char *flagsEnd,
7542 const char *conversionPosition)
override;
7547class EquatableFormatArgument {
7549 enum SpecifierSensitivity :
unsigned {
7556 enum FormatArgumentRole :
unsigned {
7564 analyze_format_string::ArgType ArgType;
7566 StringRef SpecifierLetter;
7567 CharSourceRange
Range;
7568 SourceLocation ElementLoc;
7569 FormatArgumentRole
Role : 2;
7570 SpecifierSensitivity Sensitivity : 2;
7571 unsigned Position : 14;
7572 unsigned ModifierFor : 14;
7574 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7575 bool InFunctionCall)
const;
7578 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7580 StringRef SpecifierLetter,
7581 analyze_format_string::ArgType ArgType,
7582 FormatArgumentRole
Role,
7583 SpecifierSensitivity Sensitivity,
unsigned Position,
7584 unsigned ModifierFor)
7585 : ArgType(ArgType), LengthMod(LengthMod),
7586 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7587 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7588 ModifierFor(ModifierFor) {}
7590 unsigned getPosition()
const {
return Position; }
7591 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7593 analyze_format_string::LengthModifier getLengthModifier()
const {
7594 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7596 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7598 std::string buildFormatSpecifier()
const {
7600 llvm::raw_string_ostream(result)
7601 << getLengthModifier().toString() << SpecifierLetter;
7605 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7606 const Expr *FmtExpr,
bool InFunctionCall)
const;
7610class DecomposePrintfHandler :
public CheckPrintfHandler {
7611 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7614 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7615 const Expr *origFormatExpr,
7617 unsigned numDataArgs,
bool isObjC,
const char *beg,
7619 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7621 llvm::SmallBitVector &CheckedVarArgs,
7622 UncoveredArgHandler &UncoveredArg,
7623 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7624 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7625 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7626 inFunctionCall, CallType, CheckedVarArgs,
7628 Specs(Specs), HadError(
false) {}
7632 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7634 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7636 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7637 const char *startSpecifier,
7638 unsigned specifierLen,
7639 const TargetInfo &
Target)
override;
7644bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7646 unsigned specifierLen) {
7650 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7652 startSpecifier, specifierLen,
7656void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7657 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7665 return T->isRecordType() ||
T->isComplexType();
7668bool CheckPrintfHandler::HandleAmount(
7670 const char *startSpecifier,
unsigned specifierLen) {
7672 if (HasFormatArguments()) {
7674 if (argIndex >= NumDataArgs) {
7675 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7679 getSpecifierRange(startSpecifier, specifierLen));
7689 CoveredArgs.set(argIndex);
7690 const Expr *Arg = getDataArg(argIndex);
7701 ? diag::err_printf_asterisk_wrong_type
7702 : diag::warn_printf_asterisk_wrong_type;
7703 EmitFormatDiagnostic(S.
PDiag(DiagID)
7708 getSpecifierRange(startSpecifier, specifierLen));
7718void CheckPrintfHandler::HandleInvalidAmount(
7722 const char *startSpecifier,
7723 unsigned specifierLen) {
7733 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7737 getSpecifierRange(startSpecifier, specifierLen),
7743 const char *startSpecifier,
7744 unsigned specifierLen) {
7748 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7752 getSpecifierRange(startSpecifier, specifierLen),
7757void CheckPrintfHandler::HandleIgnoredFlag(
7761 const char *startSpecifier,
7762 unsigned specifierLen) {
7764 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7768 getSpecifierRange(startSpecifier, specifierLen),
7770 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7773void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7776 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7777 getLocationOfByte(startFlag),
7779 getSpecifierRange(startFlag, flagLen));
7782void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7785 auto Range = getSpecifierRange(startFlag, flagLen);
7786 StringRef flag(startFlag, flagLen);
7787 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7788 getLocationOfByte(startFlag),
7793void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7794 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7796 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7797 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7798 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
7799 getLocationOfByte(conversionPosition),
7805 const Expr *FmtExpr,
7806 bool InFunctionCall)
const {
7807 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7808 ElementLoc,
true, Range);
7811bool EquatableFormatArgument::VerifyCompatible(
7812 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7813 bool InFunctionCall)
const {
7818 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
7819 FmtExpr, InFunctionCall);
7820 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7824 if (
Role != FAR_Data) {
7825 if (ModifierFor !=
Other.ModifierFor) {
7828 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
7829 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
7830 FmtExpr, InFunctionCall);
7831 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7837 bool HadError =
false;
7838 if (Sensitivity !=
Other.Sensitivity) {
7841 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
7842 << Sensitivity <<
Other.Sensitivity,
7843 FmtExpr, InFunctionCall);
7844 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7845 << 0 <<
Other.Range;
7848 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
7852 case MK::MatchPromotion:
7856 case MK::NoMatchTypeConfusion:
7857 case MK::NoMatchPromotionTypeConfusion:
7859 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
7860 << buildFormatSpecifier()
7861 <<
Other.buildFormatSpecifier(),
7862 FmtExpr, InFunctionCall);
7863 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7864 << 0 <<
Other.Range;
7867 case MK::NoMatchPedantic:
7869 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
7870 << buildFormatSpecifier()
7871 <<
Other.buildFormatSpecifier(),
7872 FmtExpr, InFunctionCall);
7873 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7874 << 0 <<
Other.Range;
7877 case MK::NoMatchSignedness:
7879 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
7880 << buildFormatSpecifier()
7881 <<
Other.buildFormatSpecifier(),
7882 FmtExpr, InFunctionCall);
7883 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7884 << 0 <<
Other.Range;
7890bool DecomposePrintfHandler::GetSpecifiers(
7891 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7894 StringRef
Data = FSL->getString();
7895 const char *Str =
Data.data();
7896 llvm::SmallBitVector BV;
7897 UncoveredArgHandler UA;
7898 const Expr *PrintfArgs[] = {FSL->getFormatString()};
7899 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
7911 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
7912 const EquatableFormatArgument &B) {
7913 return A.getPosition() < B.getPosition();
7918bool DecomposePrintfHandler::HandlePrintfSpecifier(
7921 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
7936 const unsigned Unset = ~0;
7937 unsigned FieldWidthIndex = Unset;
7938 unsigned PrecisionIndex = Unset;
7942 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
7943 FieldWidthIndex = Specs.size();
7944 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
7945 getLocationOfByte(FieldWidth.getStart()),
7947 FieldWidth.getArgType(S.
Context),
7948 EquatableFormatArgument::FAR_FieldWidth,
7949 EquatableFormatArgument::SS_None,
7950 FieldWidth.usesPositionalArg()
7951 ? FieldWidth.getPositionalArgIndex() - 1
7957 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
7958 PrecisionIndex = Specs.size();
7960 getSpecifierRange(startSpecifier, specifierLen),
7961 getLocationOfByte(Precision.getStart()),
7963 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
7964 EquatableFormatArgument::SS_None,
7965 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
7971 unsigned SpecIndex =
7973 if (FieldWidthIndex != Unset)
7974 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
7975 if (PrecisionIndex != Unset)
7976 Specs[PrecisionIndex].setModifierFor(SpecIndex);
7978 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
7980 Sensitivity = EquatableFormatArgument::SS_Private;
7982 Sensitivity = EquatableFormatArgument::SS_Public;
7984 Sensitivity = EquatableFormatArgument::SS_Sensitive;
7986 Sensitivity = EquatableFormatArgument::SS_None;
7989 getSpecifierRange(startSpecifier, specifierLen),
7992 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
7997 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8002 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8003 SpecIndex + 1, SpecIndex);
8011template<
typename MemberKind>
8029 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8044 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8046 if ((*MI)->getMinRequiredArguments() == 0)
8054bool CheckPrintfHandler::checkForCStrMembers(
8061 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8064 if (
Method->getMinRequiredArguments() == 0 &&
8077bool CheckPrintfHandler::HandlePrintfSpecifier(
8091 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8092 startSpecifier, specifierLen);
8100 startSpecifier, specifierLen)) {
8105 startSpecifier, specifierLen)) {
8109 if (!CS.consumesDataArgument()) {
8117 if (argIndex < NumDataArgs) {
8121 CoveredArgs.set(argIndex);
8128 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8131 if (HasFormatArguments()) {
8133 CoveredArgs.set(argIndex + 1);
8136 const Expr *Ex = getDataArg(argIndex);
8140 : ArgType::CPointerTy;
8142 EmitFormatDiagnostic(
8143 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8147 getSpecifierRange(startSpecifier, specifierLen));
8150 Ex = getDataArg(argIndex + 1);
8153 EmitFormatDiagnostic(
8154 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8158 getSpecifierRange(startSpecifier, specifierLen));
8165 if (!allowsObjCArg() && CS.isObjCArg()) {
8166 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8173 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8180 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8181 getLocationOfByte(CS.getStart()),
8183 getSpecifierRange(startSpecifier, specifierLen));
8193 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8200 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8204 getSpecifierRange(startSpecifier, specifierLen));
8207 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8211 getSpecifierRange(startSpecifier, specifierLen));
8215 const llvm::Triple &Triple =
Target.getTriple();
8217 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8218 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8219 getLocationOfByte(CS.getStart()),
8221 getSpecifierRange(startSpecifier, specifierLen));
8227 startSpecifier, specifierLen);
8233 startSpecifier, specifierLen);
8239 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8240 getLocationOfByte(startSpecifier),
8242 getSpecifierRange(startSpecifier, specifierLen));
8251 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8253 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8262 startSpecifier, specifierLen);
8265 startSpecifier, specifierLen);
8270 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8271 diag::warn_format_nonsensical_length);
8273 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8275 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8276 diag::warn_format_non_standard_conversion_spec);
8279 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8282 if (!HasFormatArguments())
8285 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8288 const Expr *Arg = getDataArg(argIndex);
8292 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8304 case Stmt::ArraySubscriptExprClass:
8305 case Stmt::CallExprClass:
8306 case Stmt::CharacterLiteralClass:
8307 case Stmt::CXXBoolLiteralExprClass:
8308 case Stmt::DeclRefExprClass:
8309 case Stmt::FloatingLiteralClass:
8310 case Stmt::IntegerLiteralClass:
8311 case Stmt::MemberExprClass:
8312 case Stmt::ObjCArrayLiteralClass:
8313 case Stmt::ObjCBoolLiteralExprClass:
8314 case Stmt::ObjCBoxedExprClass:
8315 case Stmt::ObjCDictionaryLiteralClass:
8316 case Stmt::ObjCEncodeExprClass:
8317 case Stmt::ObjCIvarRefExprClass:
8318 case Stmt::ObjCMessageExprClass:
8319 case Stmt::ObjCPropertyRefExprClass:
8320 case Stmt::ObjCStringLiteralClass:
8321 case Stmt::ObjCSubscriptRefExprClass:
8322 case Stmt::ParenExprClass:
8323 case Stmt::StringLiteralClass:
8324 case Stmt::UnaryOperatorClass:
8331static std::pair<QualType, StringRef>
8338 StringRef Name = UserTy->getDecl()->getName();
8339 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8340 .Case(
"CFIndex", Context.getNSIntegerType())
8341 .Case(
"NSInteger", Context.getNSIntegerType())
8342 .Case(
"NSUInteger", Context.getNSUIntegerType())
8343 .Case(
"SInt32", Context.IntTy)
8344 .Case(
"UInt32", Context.UnsignedIntTy)
8348 return std::make_pair(CastTy, Name);
8350 TyTy = UserTy->desugar();
8354 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8356 PE->getSubExpr()->getType(),
8365 StringRef TrueName, FalseName;
8367 std::tie(TrueTy, TrueName) =
8369 CO->getTrueExpr()->getType(),
8371 std::tie(FalseTy, FalseName) =
8373 CO->getFalseExpr()->getType(),
8374 CO->getFalseExpr());
8376 if (TrueTy == FalseTy)
8377 return std::make_pair(TrueTy, TrueName);
8378 else if (TrueTy.
isNull())
8379 return std::make_pair(FalseTy, FalseName);
8380 else if (FalseTy.
isNull())
8381 return std::make_pair(TrueTy, TrueName);
8384 return std::make_pair(
QualType(), StringRef());
8403 From = VecTy->getElementType();
8405 To = VecTy->getElementType();
8416 diag::warn_format_conversion_argument_type_mismatch_signedness,
8420 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8429 const char *StartSpecifier,
8430 unsigned SpecifierLen,
8442 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8443 ExprTy = TET->getUnderlyingExpr()->getType();
8458 getSpecifierRange(StartSpecifier, SpecifierLen);
8460 llvm::raw_svector_ostream os(FSString);
8462 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8473 getSpecifierRange(StartSpecifier, SpecifierLen);
8474 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8484 if (
Match == ArgType::Match)
8488 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8497 E = ICE->getSubExpr();
8507 if (OrigMatch == ArgType::NoMatchSignedness &&
8508 ImplicitMatch != ArgType::NoMatchSignedness)
8515 if (ImplicitMatch == ArgType::Match)
8533 if (
Match == ArgType::MatchPromotion)
8537 if (
Match == ArgType::MatchPromotion) {
8541 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8542 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8546 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8547 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8548 Match = ImplicitMatch;
8549 assert(
Match != ArgType::MatchPromotion);
8552 bool IsEnum =
false;
8553 bool IsScopedEnum =
false;
8556 IntendedTy = ED->getIntegerType();
8557 if (!ED->isScoped()) {
8558 ExprTy = IntendedTy;
8563 IsScopedEnum =
true;
8570 if (isObjCContext() &&
8581 const llvm::APInt &
V = IL->getValue();
8591 if (TD->getUnderlyingType() == IntendedTy)
8601 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8609 if (!IsScopedEnum &&
8610 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8614 IntendedTy = CastTy;
8615 ShouldNotPrintDirectly =
true;
8620 PrintfSpecifier fixedFS = FS;
8627 llvm::raw_svector_ostream os(buf);
8630 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8632 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8638 llvm_unreachable(
"expected non-matching");
8640 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8643 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8646 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8649 Diag = diag::warn_format_conversion_argument_type_mismatch;
8670 llvm::raw_svector_ostream CastFix(CastBuf);
8671 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8673 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8679 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8684 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8706 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8712 Name = TypedefTy->getDecl()->getName();
8716 ? diag::warn_format_argument_needs_cast_pedantic
8717 : diag::warn_format_argument_needs_cast;
8718 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8729 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8730 : diag::warn_format_conversion_argument_type_mismatch;
8732 EmitFormatDiagnostic(
8744 bool EmitTypeMismatch =
false;
8754 llvm_unreachable(
"expected non-matching");
8756 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8759 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8763 ? diag::err_format_conversion_argument_type_mismatch
8764 : diag::warn_format_conversion_argument_type_mismatch;
8768 EmitFormatDiagnostic(
8777 EmitTypeMismatch =
true;
8779 EmitFormatDiagnostic(
8780 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8781 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8785 checkForCStrMembers(AT, E);
8791 EmitTypeMismatch =
true;
8793 EmitFormatDiagnostic(
8794 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8795 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8808 if (EmitTypeMismatch) {
8814 EmitFormatDiagnostic(
8815 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8821 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
8822 "format string specifier index out of range");
8823 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
8833class CheckScanfHandler :
public CheckFormatHandler {
8835 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8837 unsigned firstDataArg,
unsigned numDataArgs,
8839 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8841 llvm::SmallBitVector &CheckedVarArgs,
8842 UncoveredArgHandler &UncoveredArg)
8843 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8844 numDataArgs, beg, APK, Args, formatIdx,
8845 inFunctionCall, CallType, CheckedVarArgs,
8848 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
8849 const char *startSpecifier,
8850 unsigned specifierLen)
override;
8852 bool HandleInvalidScanfConversionSpecifier(
8853 const analyze_scanf::ScanfSpecifier &FS,
8854 const char *startSpecifier,
8855 unsigned specifierLen)
override;
8857 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8862void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8864 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
8865 getLocationOfByte(end),
true,
8866 getSpecifierRange(start, end - start));
8869bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
8871 const char *startSpecifier,
8872 unsigned specifierLen) {
8876 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8878 startSpecifier, specifierLen,
8882bool CheckScanfHandler::HandleScanfSpecifier(
8884 const char *startSpecifier,
8885 unsigned specifierLen) {
8899 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
8900 startSpecifier, specifierLen);
8911 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
8926 if (argIndex < NumDataArgs) {
8930 CoveredArgs.set(argIndex);
8936 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8937 diag::warn_format_nonsensical_length);
8939 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8941 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8942 diag::warn_format_non_standard_conversion_spec);
8945 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8948 if (!HasFormatArguments())
8951 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8955 const Expr *Ex = getDataArg(argIndex);
8973 ScanfSpecifier fixedFS = FS;
8978 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8980 ? diag::warn_format_conversion_argument_type_mismatch_signedness
8981 : diag::warn_format_conversion_argument_type_mismatch;
8986 llvm::raw_svector_ostream os(buf);
8989 EmitFormatDiagnostic(
8994 getSpecifierRange(startSpecifier, specifierLen),
8996 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9003 getSpecifierRange(startSpecifier, specifierLen));
9013 const Expr *FmtExpr,
bool InFunctionCall) {
9014 bool HadError =
false;
9015 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9016 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9017 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9029 for (; FmtIter < FmtEnd; ++FmtIter) {
9033 if (FmtIter->getPosition() < RefIter->getPosition())
9037 if (FmtIter->getPosition() > RefIter->getPosition())
9041 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9045 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9046 return Arg.getPosition() != RefIter->getPosition();
9050 if (FmtIter < FmtEnd) {
9051 CheckFormatHandler::EmitFormatDiagnostic(
9052 S, InFunctionCall, FmtExpr,
9053 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9054 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9055 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9056 }
else if (RefIter < RefEnd) {
9057 CheckFormatHandler::EmitFormatDiagnostic(
9058 S, InFunctionCall, FmtExpr,
9059 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9062 << 1 << RefIter->getSourceRange();
9068 Sema &S,
const FormatStringLiteral *FExpr,
9073 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9074 bool IgnoreStringsWithoutSpecifiers) {
9076 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9077 CheckFormatHandler::EmitFormatDiagnostic(
9078 S, inFunctionCall, Args[format_idx],
9079 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9085 StringRef StrRef = FExpr->getString();
9086 const char *Str = StrRef.data();
9090 assert(
T &&
"String literal not of constant array type!");
9091 size_t TypeSize =
T->getZExtSize();
9092 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9093 const unsigned numDataArgs = Args.size() - firstDataArg;
9095 if (IgnoreStringsWithoutSpecifiers &&
9102 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9103 CheckFormatHandler::EmitFormatDiagnostic(
9104 S, inFunctionCall, Args[format_idx],
9105 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9106 FExpr->getBeginLoc(),
9112 if (StrLen == 0 && numDataArgs > 0) {
9113 CheckFormatHandler::EmitFormatDiagnostic(
9114 S, inFunctionCall, Args[format_idx],
9115 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9126 if (ReferenceFormatString ==
nullptr) {
9127 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9128 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9129 inFunctionCall, CallType, CheckedVarArgs,
9139 Type, ReferenceFormatString, FExpr->getFormatString(),
9140 inFunctionCall ?
nullptr : Args[format_idx]);
9143 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9144 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9145 CallType, CheckedVarArgs, UncoveredArg);
9165 FormatStringLiteral RefLit = AuthoritativeFormatString;
9166 FormatStringLiteral TestLit = TestedFormatString;
9168 bool DiagAtStringLiteral;
9169 if (FunctionCallArg) {
9170 Arg = FunctionCallArg;
9171 DiagAtStringLiteral =
false;
9173 Arg = TestedFormatString;
9174 DiagAtStringLiteral =
true;
9176 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9177 AuthoritativeFormatString,
Type,
9178 IsObjC,
true, RefArgs) &&
9179 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9180 DiagAtStringLiteral, FmtArgs)) {
9182 TestedFormatString, FmtArgs, Arg,
9183 DiagAtStringLiteral);
9196 FormatStringLiteral RefLit = Str;
9200 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9209 bool HadError =
false;
9210 auto Iter = Args.begin();
9211 auto End = Args.end();
9212 while (Iter != End) {
9213 const auto &FirstInGroup = *Iter;
9215 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9217 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9226 const char *Str = StrRef.data();
9229 assert(
T &&
"String literal not of constant array type!");
9230 size_t TypeSize =
T->getZExtSize();
9231 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9242 switch (AbsFunction) {
9246 case Builtin::BI__builtin_abs:
9247 return Builtin::BI__builtin_labs;
9248 case Builtin::BI__builtin_labs:
9249 return Builtin::BI__builtin_llabs;
9250 case Builtin::BI__builtin_llabs:
9253 case Builtin::BI__builtin_fabsf:
9254 return Builtin::BI__builtin_fabs;
9255 case Builtin::BI__builtin_fabs:
9256 return Builtin::BI__builtin_fabsl;
9257 case Builtin::BI__builtin_fabsl:
9260 case Builtin::BI__builtin_cabsf:
9261 return Builtin::BI__builtin_cabs;
9262 case Builtin::BI__builtin_cabs:
9263 return Builtin::BI__builtin_cabsl;
9264 case Builtin::BI__builtin_cabsl:
9267 case Builtin::BIabs:
9268 return Builtin::BIlabs;
9269 case Builtin::BIlabs:
9270 return Builtin::BIllabs;
9271 case Builtin::BIllabs:
9274 case Builtin::BIfabsf:
9275 return Builtin::BIfabs;
9276 case Builtin::BIfabs:
9277 return Builtin::BIfabsl;
9278 case Builtin::BIfabsl:
9281 case Builtin::BIcabsf:
9282 return Builtin::BIcabs;
9283 case Builtin::BIcabs:
9284 return Builtin::BIcabsl;
9285 case Builtin::BIcabsl:
9314 unsigned AbsFunctionKind) {
9315 unsigned BestKind = 0;
9316 uint64_t ArgSize = Context.getTypeSize(ArgType);
9317 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9320 if (Context.getTypeSize(ParamType) >= ArgSize) {
9323 else if (Context.hasSameType(ParamType, ArgType)) {
9339 if (
T->isIntegralOrEnumerationType())
9341 if (
T->isRealFloatingType())
9343 if (
T->isAnyComplexType())
9346 llvm_unreachable(
"Type not integer, floating, or complex");
9353 switch (ValueKind) {
9358 case Builtin::BI__builtin_fabsf:
9359 case Builtin::BI__builtin_fabs:
9360 case Builtin::BI__builtin_fabsl:
9361 case Builtin::BI__builtin_cabsf:
9362 case Builtin::BI__builtin_cabs:
9363 case Builtin::BI__builtin_cabsl:
9364 return Builtin::BI__builtin_abs;
9365 case Builtin::BIfabsf:
9366 case Builtin::BIfabs:
9367 case Builtin::BIfabsl:
9368 case Builtin::BIcabsf:
9369 case Builtin::BIcabs:
9370 case Builtin::BIcabsl:
9371 return Builtin::BIabs;
9377 case Builtin::BI__builtin_abs:
9378 case Builtin::BI__builtin_labs:
9379 case Builtin::BI__builtin_llabs:
9380 case Builtin::BI__builtin_cabsf:
9381 case Builtin::BI__builtin_cabs:
9382 case Builtin::BI__builtin_cabsl:
9383 return Builtin::BI__builtin_fabsf;
9384 case Builtin::BIabs:
9385 case Builtin::BIlabs:
9386 case Builtin::BIllabs:
9387 case Builtin::BIcabsf:
9388 case Builtin::BIcabs:
9389 case Builtin::BIcabsl:
9390 return Builtin::BIfabsf;
9396 case Builtin::BI__builtin_abs:
9397 case Builtin::BI__builtin_labs:
9398 case Builtin::BI__builtin_llabs:
9399 case Builtin::BI__builtin_fabsf:
9400 case Builtin::BI__builtin_fabs:
9401 case Builtin::BI__builtin_fabsl:
9402 return Builtin::BI__builtin_cabsf;
9403 case Builtin::BIabs:
9404 case Builtin::BIlabs:
9405 case Builtin::BIllabs:
9406 case Builtin::BIfabsf:
9407 case Builtin::BIfabs:
9408 case Builtin::BIfabsl:
9409 return Builtin::BIcabsf;
9412 llvm_unreachable(
"Unable to convert function");
9423 case Builtin::BI__builtin_abs:
9424 case Builtin::BI__builtin_fabs:
9425 case Builtin::BI__builtin_fabsf:
9426 case Builtin::BI__builtin_fabsl:
9427 case Builtin::BI__builtin_labs:
9428 case Builtin::BI__builtin_llabs:
9429 case Builtin::BI__builtin_cabs:
9430 case Builtin::BI__builtin_cabsf:
9431 case Builtin::BI__builtin_cabsl:
9432 case Builtin::BIabs:
9433 case Builtin::BIlabs:
9434 case Builtin::BIllabs:
9435 case Builtin::BIfabs:
9436 case Builtin::BIfabsf:
9437 case Builtin::BIfabsl:
9438 case Builtin::BIcabs:
9439 case Builtin::BIcabsf:
9440 case Builtin::BIcabsl:
9443 llvm_unreachable(
"Unknown Builtin type");
9449 unsigned AbsKind,
QualType ArgType) {
9450 bool EmitHeaderHint =
true;
9451 const char *HeaderName =
nullptr;
9452 std::string FunctionName;
9453 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9454 FunctionName =
"std::abs";
9455 if (ArgType->isIntegralOrEnumerationType()) {
9456 HeaderName =
"cstdlib";
9457 }
else if (ArgType->isRealFloatingType()) {
9458 HeaderName =
"cmath";
9460 llvm_unreachable(
"Invalid Type");
9469 for (
const auto *I : R) {
9472 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9474 FDecl = dyn_cast<FunctionDecl>(I);
9489 EmitHeaderHint =
false;
9507 EmitHeaderHint =
false;
9511 }
else if (!R.
empty()) {
9517 S.
Diag(Loc, diag::note_replace_abs_function)
9523 if (!EmitHeaderHint)
9526 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9530template <std::
size_t StrLen>
9532 const char (&Str)[StrLen]) {
9545 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9546 return llvm::is_contained(names, calleeName);
9551 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9552 "__builtin_nanf16",
"__builtin_nanf128"});
9554 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9555 "__builtin_inff16",
"__builtin_inff128"});
9557 llvm_unreachable(
"unknown MathCheck");
9561 if (FDecl->
getName() !=
"infinity")
9564 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9566 if (RDecl->
getName() !=
"numeric_limits")
9583 if (FPO.getNoHonorNaNs() &&
9586 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9587 << 1 << 0 <<
Call->getSourceRange();
9591 if (FPO.getNoHonorInfs() &&
9595 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9596 << 0 << 0 <<
Call->getSourceRange();
9600void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9602 if (
Call->getNumArgs() != 1)
9607 if (AbsKind == 0 && !IsStdAbs)
9610 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9611 QualType ParamType =
Call->getArg(0)->getType();
9616 std::string FunctionName =
9617 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9618 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9619 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9648 if (ArgValueKind == ParamValueKind) {
9649 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9653 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9654 << FDecl << ArgType << ParamType;
9656 if (NewAbsKind == 0)
9660 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9669 if (NewAbsKind == 0)
9672 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9673 << FDecl << ParamValueKind << ArgValueKind;
9676 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9682 if (!
Call || !FDecl)
return;
9686 if (
Call->getExprLoc().isMacroID())
return;
9689 if (
Call->getNumArgs() != 2)
return;
9692 if (!ArgList)
return;
9693 if (ArgList->size() != 1)
return;
9696 const auto& TA = ArgList->
get(0);
9698 QualType ArgType = TA.getAsType();
9702 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
9703 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
9704 if (!MTE)
return false;
9705 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9706 if (!
Num)
return false;
9707 if (
Num->getValue() != 0)
return false;
9711 const Expr *FirstArg =
Call->getArg(0);
9712 const Expr *SecondArg =
Call->getArg(1);
9713 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9714 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9717 if (IsFirstArgZero == IsSecondArgZero)
return;
9722 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9724 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9725 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9728 SourceRange RemovalRange;
9729 if (IsFirstArgZero) {
9730 RemovalRange = SourceRange(FirstRange.
getBegin(),
9737 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9752 const auto *Size = dyn_cast<BinaryOperator>(E);
9757 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9761 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9762 << SizeRange << FnName;
9763 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9768 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9779 bool &IsContained) {
9781 const Type *Ty =
T->getBaseElementTypeUnsafe();
9782 IsContained =
false;
9795 for (
auto *FD : RD->
fields()) {
9808 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
9809 if (Unary->getKind() == UETT_SizeOf)
9818 if (!
SizeOf->isArgumentType())
9819 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9826 return SizeOf->getTypeOfArgument();
9832struct SearchNonTrivialToInitializeField
9835 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
9837 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
9840 SourceLocation SL) {
9841 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9842 asDerived().visitArray(PDIK, AT, SL);
9846 Super::visitWithKind(PDIK, FT, SL);
9849 void visitARCStrong(QualType FT, SourceLocation SL) {
9852 void visitARCWeak(QualType FT, SourceLocation SL) {
9855 void visitStruct(QualType FT, SourceLocation SL) {
9860 const ArrayType *AT, SourceLocation SL) {
9861 visit(getContext().getBaseElementType(AT), SL);
9863 void visitTrivial(QualType FT, SourceLocation SL) {}
9865 static void diag(QualType RT,
const Expr *E, Sema &S) {
9866 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
9875struct SearchNonTrivialToCopyField
9877 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
9879 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
9882 SourceLocation SL) {
9883 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9884 asDerived().visitArray(PCK, AT, SL);
9888 Super::visitWithKind(PCK, FT, SL);
9891 void visitARCStrong(QualType FT, SourceLocation SL) {
9894 void visitARCWeak(QualType FT, SourceLocation SL) {
9897 void visitPtrAuth(QualType FT, SourceLocation SL) {
9900 void visitStruct(QualType FT, SourceLocation SL) {
9905 SourceLocation SL) {
9906 visit(getContext().getBaseElementType(AT), SL);
9909 SourceLocation SL) {}
9910 void visitTrivial(QualType FT, SourceLocation SL) {}
9911 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
9913 static void diag(QualType RT,
const Expr *E, Sema &S) {
9914 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
9929 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
9930 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
9954 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
9956 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
9957 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
9963 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
9966 const Expr *SizeArg =
9967 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
9969 auto isLiteralZero = [](
const Expr *E) {
9979 if (isLiteralZero(SizeArg) &&
9986 if (BId == Builtin::BIbzero ||
9989 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
9990 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
9991 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
9992 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
9993 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10001 if (BId == Builtin::BImemset &&
10005 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10006 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10011void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10018 unsigned ExpectedNumArgs =
10019 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10020 if (
Call->getNumArgs() < ExpectedNumArgs)
10023 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10024 BId == Builtin::BIstrndup ? 1 : 2);
10026 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10027 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10030 Call->getBeginLoc(),
Call->getRParenLoc()))
10039 llvm::FoldingSetNodeID SizeOfArgID;
10044 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10045 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10048 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10049 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10050 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10052 QualType DestTy = Dest->
getType();
10053 QualType PointeeTy;
10054 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10067 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10071 if (SizeOfArgID == llvm::FoldingSetNodeID())
10073 llvm::FoldingSetNodeID DestID;
10075 if (DestID == SizeOfArgID) {
10078 unsigned ActionIdx = 0;
10079 StringRef ReadableName = FnName->
getName();
10081 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10082 if (UnaryOp->getOpcode() == UO_AddrOf)
10091 SourceLocation SL = SizeOfArg->
getExprLoc();
10096 if (
SM.isMacroArgExpansion(SL)) {
10098 SL =
SM.getSpellingLoc(SL);
10099 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10101 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10106 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10113 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10124 if (SizeOfArgTy != QualType()) {
10126 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10128 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10129 << FnName << SizeOfArgTy << ArgIdx
10136 PointeeTy = DestTy;
10139 if (PointeeTy == QualType())
10144 if (
const CXXRecordDecl *ContainedRD =
10147 unsigned OperationType = 0;
10148 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10151 if (ArgIdx != 0 || IsCmp) {
10152 if (BId == Builtin::BImemcpy)
10154 else if(BId == Builtin::BImemmove)
10161 PDiag(diag::warn_dyn_class_memaccess)
10162 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10163 << IsContained << ContainedRD << OperationType
10164 <<
Call->getCallee()->getSourceRange());
10166 BId != Builtin::BImemset)
10169 PDiag(diag::warn_arc_object_memaccess)
10170 << ArgIdx << FnName << PointeeTy
10171 <<
Call->getCallee()->getSourceRange());
10178 bool NonTriviallyCopyableCXXRecord =
10182 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10185 PDiag(diag::warn_cstruct_memaccess)
10186 << ArgIdx << FnName << PointeeTy << 0);
10187 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10188 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10189 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10193 PDiag(diag::warn_cxxstruct_memaccess)
10194 << FnName << PointeeTy);
10195 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10198 PDiag(diag::warn_cstruct_memaccess)
10199 << ArgIdx << FnName << PointeeTy << 1);
10200 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10201 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10202 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10206 PDiag(diag::warn_cxxstruct_memaccess)
10207 << FnName << PointeeTy);
10216 PDiag(diag::note_bad_memaccess_silence)
10252 if (CAT->getZExtSize() <= 1)
10260void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10264 unsigned NumArgs =
Call->getNumArgs();
10265 if ((NumArgs != 3) && (NumArgs != 4))
10270 const Expr *CompareWithSrc =
nullptr;
10273 Call->getBeginLoc(),
Call->getRParenLoc()))
10278 CompareWithSrc = Ex;
10281 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10282 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10283 SizeCall->getNumArgs() == 1)
10288 if (!CompareWithSrc)
10295 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10299 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10300 if (!CompareWithSrcDRE ||
10304 const Expr *OriginalSizeArg =
Call->getArg(2);
10305 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10312 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10316 SmallString<128> sizeString;
10317 llvm::raw_svector_ostream
OS(sizeString);
10322 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10329 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10330 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10331 return D1->getDecl() == D2->getDecl();
10336 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10345void Sema::CheckStrncatArguments(
const CallExpr *CE,
10360 unsigned PatternType = 0;
10368 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10369 if (BE->getOpcode() == BO_Sub) {
10370 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10371 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10382 if (PatternType == 0)
10391 if (
SM.isMacroArgExpansion(SL)) {
10392 SL =
SM.getSpellingLoc(SL);
10393 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10398 QualType DstTy = DstArg->
getType();
10401 if (!isKnownSizeArray) {
10402 if (PatternType == 1)
10403 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10405 Diag(SL, diag::warn_strncat_src_size) << SR;
10409 if (PatternType == 1)
10410 Diag(SL, diag::warn_strncat_large_size) << SR;
10412 Diag(SL, diag::warn_strncat_src_size) << SR;
10414 SmallString<128> sizeString;
10415 llvm::raw_svector_ostream
OS(sizeString);
10423 Diag(SL, diag::note_strncat_wrong_size)
10428void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10437void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10439 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10440 const Decl *D = Lvalue->getDecl();
10441 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10442 if (!DD->getType()->isReferenceType())
10443 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10447 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10448 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10449 Lvalue->getMemberDecl());
10452void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10454 const auto *Lambda = dyn_cast<LambdaExpr>(
10459 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10460 << CalleeName << 2 ;
10463void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10465 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10466 if (Var ==
nullptr)
10470 << CalleeName << 0 << Var;
10473void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10476 llvm::raw_svector_ostream
OS(SizeString);
10479 if (Kind == clang::CK_BitCast &&
10480 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10482 if (Kind == clang::CK_IntegralToPointer &&
10484 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10487 switch (
Cast->getCastKind()) {
10488 case clang::CK_BitCast:
10489 case clang::CK_IntegralToPointer:
10490 case clang::CK_FunctionToPointerDecay:
10499 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10500 << CalleeName << 0 <<
OS.str();
10504void Sema::CheckFreeArguments(
const CallExpr *E) {
10505 const std::string CalleeName =
10510 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10512 case UnaryOperator::Opcode::UO_AddrOf:
10513 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10514 case UnaryOperator::Opcode::UO_Plus:
10515 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10520 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10522 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10524 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10525 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10526 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10532 << CalleeName << 1 ;
10537 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10538 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10542Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10551 Diag(ReturnLoc, diag::warn_null_ret)
10561 if (Op == OO_New || Op == OO_Array_New) {
10562 const FunctionProtoType *Proto
10566 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10572 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10577 if (
Context.getTargetInfo().getTriple().isPPC64())
10589 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10590 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10592 return FPLiteral && FPCast;
10595 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10601 llvm::APFloat TargetC = FPLiteral->
getValue();
10602 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10603 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10607 Diag(Loc, diag::warn_float_compare_literal)
10608 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10621 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10622 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10623 if (DRL->getDecl() == DRR->getDecl())
10631 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10632 if (FLL->isExact())
10634 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10635 if (FLR->isExact())
10639 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10640 CL &&
CL->getBuiltinCallee())
10643 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10644 CR && CR->getBuiltinCallee())
10648 Diag(Loc, diag::warn_floatingpoint_eq)
10669 IntRange(
unsigned Width,
bool NonNegative)
10670 : Width(Width), NonNegative(NonNegative) {}
10673 unsigned valueBits()
const {
10674 return NonNegative ? Width : Width - 1;
10678 static IntRange forBoolType() {
10679 return IntRange(1,
true);
10683 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
10684 return forValueOfCanonicalType(
C,
10689 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
10692 if (
const auto *VT = dyn_cast<VectorType>(
T))
10693 T = VT->getElementType().getTypePtr();
10694 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10695 T = CT->getElementType().getTypePtr();
10696 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10697 T = AT->getValueType().getTypePtr();
10699 if (!
C.getLangOpts().CPlusPlus) {
10702 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10707 if (
Enum->isFixed()) {
10708 return IntRange(
C.getIntWidth(QualType(
T, 0)),
10709 !
Enum->getIntegerType()->isSignedIntegerType());
10712 unsigned NumPositive =
Enum->getNumPositiveBits();
10713 unsigned NumNegative =
Enum->getNumNegativeBits();
10715 if (NumNegative == 0)
10716 return IntRange(NumPositive,
true);
10718 return IntRange(std::max(NumPositive + 1, NumNegative),
10722 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10723 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10736 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
10739 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10740 T = VT->getElementType().getTypePtr();
10741 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
10742 T = CT->getElementType().getTypePtr();
10743 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10744 T = AT->getValueType().getTypePtr();
10746 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10748 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10749 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10758 static IntRange join(IntRange L, IntRange R) {
10759 bool Unsigned = L.NonNegative && R.NonNegative;
10760 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10761 L.NonNegative && R.NonNegative);
10765 static IntRange bit_and(IntRange L, IntRange R) {
10766 unsigned Bits = std::max(L.Width, R.Width);
10767 bool NonNegative =
false;
10768 if (L.NonNegative) {
10769 Bits = std::min(Bits, L.Width);
10770 NonNegative =
true;
10772 if (R.NonNegative) {
10773 Bits = std::min(Bits, R.Width);
10774 NonNegative =
true;
10776 return IntRange(Bits, NonNegative);
10780 static IntRange sum(IntRange L, IntRange R) {
10781 bool Unsigned = L.NonNegative && R.NonNegative;
10782 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10787 static IntRange difference(IntRange L, IntRange R) {
10791 bool CanWiden = !L.NonNegative || !R.NonNegative;
10792 bool Unsigned = L.NonNegative && R.Width == 0;
10793 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10799 static IntRange product(IntRange L, IntRange R) {
10803 bool CanWiden = !L.NonNegative && !R.NonNegative;
10804 bool Unsigned = L.NonNegative && R.NonNegative;
10805 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10810 static IntRange rem(IntRange L, IntRange R) {
10814 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10822 if (value.isSigned() && value.isNegative())
10823 return IntRange(value.getSignificantBits(),
false);
10825 if (value.getBitWidth() > MaxWidth)
10826 value = value.trunc(MaxWidth);
10830 return IntRange(value.getActiveBits(),
true);
10834 if (result.
isInt())
10841 R = IntRange::join(R, El);
10849 return IntRange::join(R, I);
10864 Ty = AtomicRHS->getValueType();
10883 bool InConstantContext,
10884 bool Approximate) {
10895 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
10896 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
10900 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
10902 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
10903 CE->getCastKind() == CK_BooleanToSignedIntegral;
10906 if (!isIntegerCast)
10907 return OutputTypeRange;
10910 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
10911 InConstantContext, Approximate);
10913 return std::nullopt;
10916 if (SubRange->Width >= OutputTypeRange.Width)
10917 return OutputTypeRange;
10921 return IntRange(SubRange->Width,
10922 SubRange->NonNegative || OutputTypeRange.NonNegative);
10925 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
10928 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
10930 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
10931 InConstantContext, Approximate);
10936 Expr *TrueExpr = CO->getTrueExpr();
10938 return std::nullopt;
10940 std::optional<IntRange> L =
10943 return std::nullopt;
10945 Expr *FalseExpr = CO->getFalseExpr();
10947 return std::nullopt;
10949 std::optional<IntRange> R =
10952 return std::nullopt;
10954 return IntRange::join(*L, *R);
10957 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
10958 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
10960 switch (BO->getOpcode()) {
10962 llvm_unreachable(
"builtin <=> should have class type");
10973 return IntRange::forBoolType();
11002 Combine = IntRange::bit_and;
11010 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11011 if (I->getValue() == 1) {
11012 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11013 return IntRange(R.Width,
true);
11023 case BO_ShrAssign: {
11025 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11027 return std::nullopt;
11031 if (std::optional<llvm::APSInt> shift =
11032 BO->getRHS()->getIntegerConstantExpr(
C)) {
11033 if (shift->isNonNegative()) {
11034 if (shift->uge(L->Width))
11035 L->Width = (L->NonNegative ? 0 : 1);
11037 L->Width -= shift->getZExtValue();
11051 Combine = IntRange::sum;
11055 if (BO->getLHS()->getType()->isPointerType())
11058 Combine = IntRange::difference;
11063 Combine = IntRange::product;
11072 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11074 return std::nullopt;
11077 if (std::optional<llvm::APSInt> divisor =
11078 BO->getRHS()->getIntegerConstantExpr(
C)) {
11079 unsigned log2 = divisor->logBase2();
11080 if (
log2 >= L->Width)
11081 L->Width = (L->NonNegative ? 0 : 1);
11083 L->Width = std::min(L->Width -
log2, MaxWidth);
11091 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11093 return std::nullopt;
11095 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11099 Combine = IntRange::rem;
11111 unsigned opWidth =
C.getIntWidth(
T);
11113 InConstantContext, Approximate);
11115 return std::nullopt;
11118 InConstantContext, Approximate);
11120 return std::nullopt;
11122 IntRange
C = Combine(*L, *R);
11123 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11124 C.Width = std::min(
C.Width, MaxWidth);
11128 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11129 switch (UO->getOpcode()) {
11132 return IntRange::forBoolType();
11146 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11149 return std::nullopt;
11154 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11164 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11167 return std::nullopt;
11172 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11182 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11183 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11187 return IntRange(BitField->getBitWidthValue(),
11188 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11191 return std::nullopt;
11197 bool InConstantContext,
11198 bool Approximate) {
11207 const llvm::fltSemantics &Src,
11208 const llvm::fltSemantics &Tgt) {
11209 llvm::APFloat truncated = value;
11212 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11213 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11215 return truncated.bitwiseIsEqual(value);
11224 const llvm::fltSemantics &Src,
11225 const llvm::fltSemantics &Tgt) {
11242 bool IsListInit =
false);
11257 return MacroName !=
"YES" && MacroName !=
"NO" &&
11258 MacroName !=
"true" && MacroName !=
"false";
11266 (!E->
getType()->isSignedIntegerType() ||
11281struct PromotedRange {
11283 llvm::APSInt PromotedMin;
11285 llvm::APSInt PromotedMax;
11287 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11289 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11290 else if (R.Width >= BitWidth && !
Unsigned) {
11294 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11295 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11297 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11298 .extOrTrunc(BitWidth);
11299 PromotedMin.setIsUnsigned(
Unsigned);
11301 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11302 .extOrTrunc(BitWidth);
11303 PromotedMax.setIsUnsigned(
Unsigned);
11308 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11318 InRangeFlag = 0x40,
11321 Min =
LE | InRangeFlag,
11322 InRange = InRangeFlag,
11323 Max =
GE | InRangeFlag,
11326 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11331 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11332 Value.isUnsigned() == PromotedMin.isUnsigned());
11333 if (!isContiguous()) {
11334 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11335 if (
Value.isMinValue())
return Min;
11336 if (
Value.isMaxValue())
return Max;
11337 if (
Value >= PromotedMin)
return InRange;
11338 if (
Value <= PromotedMax)
return InRange;
11342 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11343 case -1:
return Less;
11344 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11346 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11347 case -1:
return InRange;
11348 case 0:
return Max;
11353 llvm_unreachable(
"impossible compare result");
11356 static std::optional<StringRef>
11358 if (Op == BO_Cmp) {
11360 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11362 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11363 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11364 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11365 return std::nullopt;
11372 }
else if (Op == BO_NE) {
11376 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11383 if (Op == BO_GE || Op == BO_LE)
11384 std::swap(TrueFlag, FalseFlag);
11387 return StringRef(
"true");
11389 return StringRef(
"false");
11390 return std::nullopt;
11397 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11398 if (ICE->getCastKind() != CK_IntegralCast &&
11399 ICE->getCastKind() != CK_NoOp)
11401 E = ICE->getSubExpr();
11410 enum ConstantValueKind {
11415 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11416 return BL->getValue() ? ConstantValueKind::LiteralTrue
11417 : ConstantValueKind::LiteralFalse;
11418 return ConstantValueKind::Miscellaneous;
11423 const llvm::APSInt &
Value,
11424 bool RhsConstant) {
11446 if (!OtherValueRange)
11451 OtherT = AT->getValueType();
11452 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11456 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11462 bool OtherIsBooleanDespiteType =
11464 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11465 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11469 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11470 Value.isUnsigned());
11471 auto Cmp = OtherPromotedValueRange.compare(
Value);
11472 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11478 bool TautologicalTypeCompare =
false;
11480 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11481 Value.isUnsigned());
11482 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11485 TautologicalTypeCompare =
true;
11493 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11502 bool InRange = Cmp & PromotedRange::InRangeFlag;
11508 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11509 Other->getType()->isUnsignedIntegerOrEnumerationType())
11510 TautologicalTypeCompare =
true;
11515 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11516 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11520 llvm::raw_svector_ostream OS(PrettySourceValue);
11522 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11523 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11525 OS << (BL->getValue() ?
"YES" :
"NO");
11530 if (!TautologicalTypeCompare) {
11532 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11538 if (IsObjCSignedCharBool) {
11540 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11541 << OS.str() << *Result);
11548 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11552 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11553 : diag::warn_tautological_bool_compare)
11555 << OtherIsBooleanDespiteType << *Result
11562 ? diag::warn_unsigned_enum_always_true_comparison
11563 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11564 : diag::warn_unsigned_always_true_comparison)
11565 : diag::warn_tautological_constant_compare;
11568 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11601 if (
T->isIntegralType(S.
Context)) {
11602 std::optional<llvm::APSInt> RHSValue =
11604 std::optional<llvm::APSInt> LHSValue =
11608 if (RHSValue && LHSValue)
11612 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11614 const bool RhsConstant = (
bool)RHSValue;
11615 Expr *Const = RhsConstant ? RHS : LHS;
11617 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11626 if (!
T->hasUnsignedIntegerRepresentation()) {
11640 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11642 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11648 Expr *signedOperand, *unsignedOperand;
11651 "unsigned comparison between two signed integer expressions?");
11652 signedOperand = LHS;
11653 unsignedOperand = RHS;
11655 signedOperand = RHS;
11656 unsignedOperand = LHS;
11662 std::optional<IntRange> signedRange =
11674 if (signedRange->NonNegative)
11686 if (!unsignedRange)
11691 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11693 if (unsignedRange->Width < comparisonWidth)
11698 S.
PDiag(diag::warn_mixed_sign_comparison)
11717 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11722 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11723 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11724 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11725 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11726 << BitfieldEnumDecl;
11733 Init->isValueDependent() ||
11734 Init->isTypeDependent())
11737 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11747 const PreferredTypeAttr *PTAttr =
nullptr;
11749 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11751 ED = PTAttr->getType()->getAsEnumDecl();
11759 bool SignedEnum = ED->getNumNegativeBits() > 0;
11766 unsigned DiagID = 0;
11767 if (SignedEnum && !SignedBitfield) {
11770 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11772 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11773 }
else if (SignedBitfield && !SignedEnum &&
11774 ED->getNumPositiveBits() == FieldWidth) {
11777 ? diag::warn_signed_bitfield_enum_conversion
11778 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11781 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11786 << SignedEnum << TypeRange;
11788 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11795 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11796 ED->getNumNegativeBits())
11797 : ED->getNumPositiveBits();
11800 if (BitsNeeded > FieldWidth) {
11804 ? diag::warn_bitfield_too_small_for_enum
11805 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11806 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11810 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11818 llvm::APSInt
Value = Result.Val.getInt();
11820 unsigned OriginalWidth =
Value.getBitWidth();
11826 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11827 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11834 if (!
Value.isSigned() ||
Value.isNegative())
11835 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11836 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11837 OriginalWidth =
Value.getSignificantBits();
11839 if (OriginalWidth <= FieldWidth)
11843 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11847 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11848 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11852 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11854 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11855 ? diag::warn_impcast_single_bit_bitield_precision_constant
11856 : diag::warn_impcast_bitfield_precision_constant)
11857 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11858 <<
Init->getSourceRange();
11890 bool PruneControlFlow =
false) {
11897 if (
T.hasAddressSpace())
11899 if (PruneControlFlow) {
11913 bool PruneControlFlow =
false) {
11920 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
11925 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
11926 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
11931 llvm::APFloat
Value(0.0);
11937 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
11942 diag::warn_impcast_float_integer, PruneWarnings);
11945 bool isExact =
false;
11948 T->hasUnsignedIntegerRepresentation());
11949 llvm::APFloat::opStatus Result =
Value.convertToInteger(
11950 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
11958 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
11959 precision = (precision * 59 + 195) / 196;
11960 Value.toString(PrettySourceValue, precision);
11964 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
11965 << PrettySourceValue);
11968 if (Result == llvm::APFloat::opOK && isExact) {
11969 if (IsLiteral)
return;
11970 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
11976 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
11979 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
11980 : diag::warn_impcast_float_to_integer_out_of_range,
11983 unsigned DiagID = 0;
11986 DiagID = diag::warn_impcast_literal_float_to_integer;
11987 }
else if (IntegerValue == 0) {
11988 if (
Value.isZero()) {
11990 diag::warn_impcast_float_integer, PruneWarnings);
11993 DiagID = diag::warn_impcast_float_to_integer_zero;
11995 if (IntegerValue.isUnsigned()) {
11996 if (!IntegerValue.isMaxValue()) {
11998 diag::warn_impcast_float_integer, PruneWarnings);
12001 if (!IntegerValue.isMaxSignedValue() &&
12002 !IntegerValue.isMinSignedValue()) {
12004 diag::warn_impcast_float_integer, PruneWarnings);
12008 DiagID = diag::warn_impcast_float_to_integer;
12013 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12015 IntegerValue.toString(PrettyTargetValue);
12017 if (PruneWarnings) {
12020 << E->
getType() <<
T.getUnqualifiedType()
12021 << PrettySourceValue << PrettyTargetValue
12025 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12034 "Must be compound assignment operation");
12045 ->getComputationResultType()
12052 if (ResultBT->isInteger())
12054 E->
getExprLoc(), diag::warn_impcast_float_integer);
12056 if (!ResultBT->isFloatingPoint())
12065 diag::warn_impcast_float_result_precision);
12070 if (!Range.Width)
return "0";
12072 llvm::APSInt ValueInRange =
Value;
12073 ValueInRange.setIsSigned(!Range.NonNegative);
12074 ValueInRange = ValueInRange.trunc(Range.Width);
12075 return toString(ValueInRange, 10);
12085 const Type *Source =
12087 if (
Target->isDependentType())
12090 const auto *FloatCandidateBT =
12091 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12092 const Type *BoolCandidateType = ToBool ?
Target : Source;
12095 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12100 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12106 S, TheCall->
getArg(I - 1),
false));
12108 S, TheCall->
getArg(I + 1),
false));
12113 diag::warn_impcast_floating_point_to_bool);
12128 if (!IsGNUNullExpr && !HasNullPtrType)
12132 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12133 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12136 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12149 if (IsGNUNullExpr && Loc.
isMacroID()) {
12152 if (MacroName ==
"NULL")
12160 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12174 const char FirstLiteralCharacter =
12176 if (FirstLiteralCharacter ==
'0')
12182 if (CC.
isValid() &&
T->isCharType()) {
12183 const char FirstContextCharacter =
12185 if (FirstContextCharacter ==
'{')
12193 const auto *IL = dyn_cast<IntegerLiteral>(E);
12195 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12196 if (UO->getOpcode() == UO_Minus)
12197 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12208 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12212 if (Opc == BO_Shl) {
12215 if (LHS && LHS->getValue() == 0)
12216 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12218 RHS->getValue().isNonNegative() &&
12220 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12221 << (Result.Val.getInt() != 0);
12223 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12230 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12235 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12236 (RHS->getValue() == 0 || RHS->getValue() == 1))
12239 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12240 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12248 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12253 llvm::APSInt
Value(32);
12254 Value = Result.Val.getInt();
12255 bool IsASCII =
Value <= 0x7F;
12256 bool IsBMP =
Value <= 0xD7FF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12257 bool ConversionPreservesSemantics =
12258 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12260 if (!ConversionPreservesSemantics) {
12261 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12262 const llvm::APSInt &
Value) {
12263 if (
T->isChar8Type())
12264 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12265 if (
T->isChar16Type())
12266 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12267 assert(
T->isChar32Type());
12268 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12271 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12280 LosesPrecision ? diag::warn_impcast_unicode_precision
12281 : diag::warn_impcast_unicode_char_type);
12295 From = MaybePointee;
12302 if (FromFn->getCFIUncheckedCalleeAttr() &&
12303 !ToFn->getCFIUncheckedCalleeAttr())
12305 if (!FromFn->getCFIUncheckedCalleeAttr() &&
12306 ToFn->getCFIUncheckedCalleeAttr())
12314 From =
Context.getCanonicalType(From);
12315 To =
Context.getCanonicalType(To);
12316 return ::AdjustingCFIUncheckedCallee(From, To) ==
Discarding;
12320 From =
Context.getCanonicalType(From);
12321 To =
Context.getCanonicalType(To);
12322 return ::AdjustingCFIUncheckedCallee(From, To) ==
Adding;
12326 bool *ICContext,
bool IsListInit) {
12331 if (Source ==
Target)
return;
12332 if (
Target->isDependentType())
return;
12342 if (Source->isAtomicType())
12346 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12352 diag::warn_impcast_string_literal_to_bool);
12358 diag::warn_impcast_objective_c_literal_to_bool);
12360 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12370 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12373 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12375 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12384 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12386 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12391 if (
Target->isSveVLSBuiltinType() &&
12398 if (
Target->isRVVVLSBuiltinType() &&
12408 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12415 diag::warn_hlsl_impcast_vector_truncation);
12427 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12428 Target = VecTy->getElementType().getTypePtr();
12438 ? diag::err_impcast_complex_scalar
12439 : diag::warn_impcast_complex_scalar);
12446 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12452 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12455 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12457 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12499 else if (Order < 0) {
12509 if (TargetBT && TargetBT->
isInteger()) {
12536 diag::warn_impcast_floating_point_to_bool);
12544 if (Source->isFixedPointType()) {
12545 if (
Target->isUnsaturatedFixedPointType()) {
12549 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12550 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12551 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12554 PDiag(diag::warn_impcast_fixed_point_range)
12555 <<
Value.toString() <<
T
12561 }
else if (
Target->isIntegerType()) {
12565 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12568 llvm::APSInt IntResult = FXResult.convertToInt(
12569 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12574 PDiag(diag::warn_impcast_fixed_point_range)
12575 << FXResult.toString() <<
T
12582 }
else if (
Target->isUnsaturatedFixedPointType()) {
12583 if (Source->isIntegerType()) {
12590 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12595 PDiag(diag::warn_impcast_fixed_point_range)
12616 unsigned int SourcePrecision =
SourceRange->Width;
12620 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12623 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12624 SourcePrecision > TargetPrecision) {
12626 if (std::optional<llvm::APSInt> SourceInt =
12631 llvm::APFloat TargetFloatValue(
12633 llvm::APFloat::opStatus ConversionStatus =
12634 TargetFloatValue.convertFromAPInt(
12636 llvm::APFloat::rmNearestTiesToEven);
12638 if (ConversionStatus != llvm::APFloat::opOK) {
12640 SourceInt->toString(PrettySourceValue, 10);
12642 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12646 PDiag(diag::warn_impcast_integer_float_precision_constant)
12647 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12653 diag::warn_impcast_integer_float_precision);
12662 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12667 if (
Target->isBooleanType())
12671 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12675 if (!Source->isIntegerType() || !
Target->isIntegerType())
12680 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12683 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
12686 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12691 if (!LikelySourceRange)
12694 IntRange SourceTypeRange =
12695 IntRange::forTargetOfCanonicalType(
Context, Source);
12696 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12698 if (LikelySourceRange->Width > TargetRange.Width) {
12704 llvm::APSInt
Value(32);
12714 PDiag(diag::warn_impcast_integer_precision_constant)
12715 << PrettySourceValue << PrettyTargetValue
12725 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12726 if (UO->getOpcode() == UO_Minus)
12728 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12731 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
12735 diag::warn_impcast_integer_precision);
12738 if (TargetRange.Width > SourceTypeRange.Width) {
12739 if (
auto *UO = dyn_cast<UnaryOperator>(E))
12740 if (UO->getOpcode() == UO_Minus)
12741 if (Source->isUnsignedIntegerType()) {
12742 if (
Target->isUnsignedIntegerType())
12744 diag::warn_impcast_high_order_zero_bits);
12745 if (
Target->isSignedIntegerType())
12747 diag::warn_impcast_nonnegative_result);
12751 if (TargetRange.Width == LikelySourceRange->Width &&
12752 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12753 Source->isSignedIntegerType()) {
12767 PDiag(diag::warn_impcast_integer_precision_constant)
12768 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12778 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12779 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12780 LikelySourceRange->Width == TargetRange.Width))) {
12784 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12786 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
12790 unsigned DiagID = diag::warn_impcast_integer_sign;
12798 DiagID = diag::warn_impcast_integer_sign_conditional;
12815 Source =
Context.getCanonicalType(SourceType).getTypePtr();
12817 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
12818 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
12819 if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
12820 TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
12821 SourceEnum != TargetEnum) {
12826 diag::warn_impcast_different_enum_types);
12840 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
12853 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
12854 TrueExpr = BCO->getCommon();
12856 bool Suspicious =
false;
12860 if (
T->isBooleanType())
12865 if (!Suspicious)
return;
12868 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12875 Suspicious =
false;
12880 E->
getType(), CC, &Suspicious);
12897struct AnalyzeImplicitConversionsWorkItem {
12906 bool ExtraCheckForImplicitConversion,
12909 WorkList.push_back({E, CC,
false});
12911 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
12918 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
12920 Expr *OrigE = Item.E;
12939 Expr *SourceExpr = E;
12944 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12945 if (
auto *Src = OVE->getSourceExpr())
12948 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
12949 if (UO->getOpcode() == UO_Not &&
12950 UO->getSubExpr()->isKnownToHaveBooleanValue())
12951 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
12955 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
12956 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
12957 BO->getLHS()->isKnownToHaveBooleanValue() &&
12958 BO->getRHS()->isKnownToHaveBooleanValue() &&
12959 BO->getLHS()->HasSideEffects(S.
Context) &&
12960 BO->getRHS()->HasSideEffects(S.
Context)) {
12971 if (SR.str() ==
"&" || SR.str() ==
"|") {
12973 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
12974 << (BO->getOpcode() == BO_And ?
"&" :
"|")
12977 BO->getOperatorLoc(),
12978 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
12979 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
12981 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
12999 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13005 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13020 for (
auto *SE : POE->semantics())
13021 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13022 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13026 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13027 E = CE->getSubExpr();
13033 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13034 if (InitListE->getNumInits() == 1) {
13035 E = InitListE->getInit(0);
13042 WorkList.push_back({E, CC, IsListInit});
13046 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13047 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13051 if (OutArgE->isInOut())
13052 WorkList.push_back(
13053 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13054 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13060 if (BO->isComparisonOp())
13064 if (BO->getOpcode() == BO_Assign)
13067 if (BO->isAssignmentOp())
13083 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13085 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13089 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13090 if (ChildExpr == CSE->getOperand())
13096 if (IsLogicalAndOperator &&
13101 WorkList.push_back({ChildExpr, CC, IsListInit});
13115 if (
U->getOpcode() == UO_LNot) {
13117 }
else if (
U->getOpcode() != UO_AddrOf) {
13118 if (
U->getSubExpr()->getType()->isAtomicType())
13119 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13120 diag::warn_atomic_implicit_seq_cst);
13131 WorkList.push_back({OrigE, CC, IsListInit});
13132 while (!WorkList.empty())
13144 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13147 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13148 if (!M->getMemberDecl()->getType()->isReferenceType())
13150 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13151 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13153 FD =
Call->getDirectCallee();
13162 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13176 if (
SM.isMacroBodyExpansion(Loc))
13178 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13202 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13203 : diag::warn_this_bool_conversion;
13208 bool IsAddressOf =
false;
13210 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13211 if (UO->getOpcode() != UO_AddrOf)
13213 IsAddressOf =
true;
13214 E = UO->getSubExpr();
13218 unsigned DiagID = IsCompare
13219 ? diag::warn_address_of_reference_null_compare
13220 : diag::warn_address_of_reference_bool_conversion;
13228 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13231 llvm::raw_string_ostream S(Str);
13233 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13234 : diag::warn_cast_nonnull_to_bool;
13237 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13242 if (
auto *Callee =
Call->getDirectCallee()) {
13243 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13244 ComplainAboutNonnullParamOrCall(A);
13253 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13254 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13255 MRecordDecl && MRecordDecl->isLambda()) {
13258 << MRecordDecl->getSourceRange() << Range << IsEqual;
13268 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13269 D = M->getMemberDecl();
13277 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13280 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13281 ComplainAboutNonnullParamOrCall(A);
13285 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13289 auto ParamIter = llvm::find(FD->
parameters(), PV);
13291 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13295 ComplainAboutNonnullParamOrCall(
NonNull);
13300 if (ArgNo.getASTIndex() == ParamNo) {
13301 ComplainAboutNonnullParamOrCall(
NonNull);
13311 const bool IsArray =
T->isArrayType();
13312 const bool IsFunction =
T->isFunctionType();
13315 if (IsAddressOf && IsFunction) {
13320 if (!IsAddressOf && !IsFunction && !IsArray)
13325 llvm::raw_string_ostream S(Str);
13328 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13329 : diag::warn_impcast_pointer_to_bool;
13336 DiagType = AddressOf;
13337 else if (IsFunction)
13338 DiagType = FunctionPointer;
13340 DiagType = ArrayPointer;
13342 llvm_unreachable(
"Could not determine diagnostic.");
13344 << Range << IsEqual;
13357 if (ReturnType.
isNull())
13395 CheckArrayAccess(E);
13405void Sema::CheckForIntOverflow (
const Expr *E) {
13407 SmallVector<const Expr *, 2> Exprs(1, E);
13410 const Expr *OriginalE = Exprs.pop_back_val();
13418 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13419 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13422 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13423 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13424 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13426 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13427 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13428 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13429 Exprs.push_back(Temporary->getSubExpr());
13430 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13431 Exprs.push_back(Array->getIdx());
13432 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13433 Exprs.push_back(Compound->getInitializer());
13434 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13435 New &&
New->isArray()) {
13436 if (
auto ArraySize =
New->getArraySize())
13437 Exprs.push_back(*ArraySize);
13438 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13439 Exprs.push_back(MTE->getSubExpr());
13440 }
while (!Exprs.empty());
13448 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13455 class SequenceTree {
13457 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13458 unsigned Parent : 31;
13459 LLVM_PREFERRED_TYPE(
bool)
13460 unsigned Merged : 1;
13462 SmallVector<Value, 8> Values;
13468 friend class SequenceTree;
13472 explicit Seq(
unsigned N) : Index(N) {}
13475 Seq() : Index(0) {}
13478 SequenceTree() { Values.push_back(
Value(0)); }
13479 Seq root()
const {
return Seq(0); }
13484 Seq allocate(
Seq Parent) {
13485 Values.push_back(
Value(Parent.Index));
13486 return Seq(Values.size() - 1);
13490 void merge(
Seq S) {
13491 Values[S.Index].Merged =
true;
13497 bool isUnsequenced(
Seq Cur,
Seq Old) {
13498 unsigned C = representative(Cur.Index);
13499 unsigned Target = representative(Old.Index);
13503 C = Values[
C].Parent;
13510 unsigned representative(
unsigned K) {
13511 if (Values[K].Merged)
13513 return Values[K].Parent = representative(Values[K].Parent);
13519 using Object =
const NamedDecl *;
13533 UK_ModAsSideEffect,
13535 UK_Count = UK_ModAsSideEffect + 1
13541 const Expr *UsageExpr =
nullptr;
13542 SequenceTree::Seq
Seq;
13548 Usage Uses[UK_Count];
13551 bool Diagnosed =
false;
13555 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13563 UsageInfoMap UsageMap;
13566 SequenceTree::Seq Region;
13570 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13574 SmallVectorImpl<const Expr *> &WorkList;
13581 struct SequencedSubexpression {
13582 SequencedSubexpression(SequenceChecker &
Self)
13583 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13584 Self.ModAsSideEffect = &ModAsSideEffect;
13587 ~SequencedSubexpression() {
13588 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13592 UsageInfo &UI =
Self.UsageMap[M.first];
13593 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13594 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13595 SideEffectUsage = M.second;
13597 Self.ModAsSideEffect = OldModAsSideEffect;
13600 SequenceChecker &
Self;
13601 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13602 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13609 class EvaluationTracker {
13611 EvaluationTracker(SequenceChecker &
Self)
13613 Self.EvalTracker =
this;
13616 ~EvaluationTracker() {
13617 Self.EvalTracker = Prev;
13619 Prev->EvalOK &= EvalOK;
13622 bool evaluate(
const Expr *E,
bool &
Result) {
13627 Self.SemaRef.isConstantEvaluatedContext());
13632 SequenceChecker &
Self;
13633 EvaluationTracker *Prev;
13634 bool EvalOK =
true;
13635 } *EvalTracker =
nullptr;
13639 Object getObject(
const Expr *E,
bool Mod)
const {
13641 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13642 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13643 return getObject(UO->getSubExpr(), Mod);
13644 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13645 if (BO->getOpcode() == BO_Comma)
13646 return getObject(BO->getRHS(), Mod);
13647 if (Mod && BO->isAssignmentOp())
13648 return getObject(BO->getLHS(), Mod);
13649 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13652 return ME->getMemberDecl();
13653 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13662 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13664 Usage &U = UI.Uses[UK];
13665 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
13669 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13670 ModAsSideEffect->push_back(std::make_pair(O, U));
13672 U.UsageExpr = UsageExpr;
13682 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13683 UsageKind OtherKind,
bool IsModMod) {
13687 const Usage &U = UI.Uses[OtherKind];
13688 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
13691 const Expr *Mod = U.UsageExpr;
13692 const Expr *ModOrUse = UsageExpr;
13693 if (OtherKind == UK_Use)
13694 std::swap(Mod, ModOrUse);
13698 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13699 : diag::warn_unsequenced_mod_use)
13700 << O << SourceRange(ModOrUse->
getExprLoc()));
13701 UI.Diagnosed =
true;
13730 void notePreUse(Object O,
const Expr *UseExpr) {
13731 UsageInfo &UI = UsageMap[O];
13733 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13736 void notePostUse(Object O,
const Expr *UseExpr) {
13737 UsageInfo &UI = UsageMap[O];
13738 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13740 addUsage(O, UI, UseExpr, UK_Use);
13743 void notePreMod(Object O,
const Expr *ModExpr) {
13744 UsageInfo &UI = UsageMap[O];
13746 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13747 checkUsage(O, UI, ModExpr, UK_Use,
false);
13750 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13751 UsageInfo &UI = UsageMap[O];
13752 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13754 addUsage(O, UI, ModExpr, UK);
13758 SequenceChecker(Sema &S,
const Expr *E,
13759 SmallVectorImpl<const Expr *> &WorkList)
13760 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
13764 (void)this->WorkList;
13767 void VisitStmt(
const Stmt *S) {
13771 void VisitExpr(
const Expr *E) {
13773 Base::VisitStmt(E);
13776 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
13777 for (
auto *Sub : CSE->
children()) {
13778 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13793 void VisitCastExpr(
const CastExpr *E) {
13805 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13806 const Expr *SequencedAfter) {
13807 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
13808 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
13809 SequenceTree::Seq OldRegion = Region;
13812 SequencedSubexpression SeqBefore(*
this);
13813 Region = BeforeRegion;
13814 Visit(SequencedBefore);
13817 Region = AfterRegion;
13818 Visit(SequencedAfter);
13820 Region = OldRegion;
13822 Tree.merge(BeforeRegion);
13823 Tree.merge(AfterRegion);
13826 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
13831 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13838 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13839 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13840 void VisitBinPtrMem(
const BinaryOperator *BO) {
13845 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13852 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13853 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13854 void VisitBinShlShr(
const BinaryOperator *BO) {
13858 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13865 void VisitBinComma(
const BinaryOperator *BO) {
13870 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13873 void VisitBinAssign(
const BinaryOperator *BO) {
13874 SequenceTree::Seq RHSRegion;
13875 SequenceTree::Seq LHSRegion;
13877 RHSRegion = Tree.allocate(Region);
13878 LHSRegion = Tree.allocate(Region);
13880 RHSRegion = Region;
13881 LHSRegion = Region;
13883 SequenceTree::Seq OldRegion = Region;
13899 SequencedSubexpression SeqBefore(*
this);
13900 Region = RHSRegion;
13904 Region = LHSRegion;
13908 notePostUse(O, BO);
13912 Region = LHSRegion;
13916 notePostUse(O, BO);
13918 Region = RHSRegion;
13926 Region = OldRegion;
13930 : UK_ModAsSideEffect);
13932 Tree.merge(RHSRegion);
13933 Tree.merge(LHSRegion);
13937 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
13938 VisitBinAssign(CAO);
13941 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13942 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13943 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
13946 return VisitExpr(UO);
13954 : UK_ModAsSideEffect);
13957 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13958 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13959 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
13962 return VisitExpr(UO);
13966 notePostMod(O, UO, UK_ModAsSideEffect);
13969 void VisitBinLOr(
const BinaryOperator *BO) {
13975 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
13976 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
13977 SequenceTree::Seq OldRegion = Region;
13979 EvaluationTracker Eval(*
this);
13981 SequencedSubexpression Sequenced(*
this);
13982 Region = LHSRegion;
13989 bool EvalResult =
false;
13990 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13991 bool ShouldVisitRHS = !EvalOK || !EvalResult;
13992 if (ShouldVisitRHS) {
13993 Region = RHSRegion;
13997 Region = OldRegion;
13998 Tree.merge(LHSRegion);
13999 Tree.merge(RHSRegion);
14002 void VisitBinLAnd(
const BinaryOperator *BO) {
14008 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14009 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14010 SequenceTree::Seq OldRegion = Region;
14012 EvaluationTracker Eval(*
this);
14014 SequencedSubexpression Sequenced(*
this);
14015 Region = LHSRegion;
14021 bool EvalResult =
false;
14022 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14023 bool ShouldVisitRHS = !EvalOK || EvalResult;
14024 if (ShouldVisitRHS) {
14025 Region = RHSRegion;
14029 Region = OldRegion;
14030 Tree.merge(LHSRegion);
14031 Tree.merge(RHSRegion);
14034 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14039 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14055 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14056 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14057 SequenceTree::Seq OldRegion = Region;
14059 EvaluationTracker Eval(*
this);
14061 SequencedSubexpression Sequenced(*
this);
14062 Region = ConditionRegion;
14072 bool EvalResult =
false;
14073 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14074 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14075 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14076 if (ShouldVisitTrueExpr) {
14077 Region = TrueRegion;
14080 if (ShouldVisitFalseExpr) {
14081 Region = FalseRegion;
14085 Region = OldRegion;
14086 Tree.merge(ConditionRegion);
14087 Tree.merge(TrueRegion);
14088 Tree.merge(FalseRegion);
14091 void VisitCallExpr(
const CallExpr *CE) {
14103 SequencedSubexpression Sequenced(*
this);
14108 SequenceTree::Seq CalleeRegion;
14109 SequenceTree::Seq OtherRegion;
14110 if (SemaRef.getLangOpts().CPlusPlus17) {
14111 CalleeRegion = Tree.allocate(Region);
14112 OtherRegion = Tree.allocate(Region);
14114 CalleeRegion = Region;
14115 OtherRegion = Region;
14117 SequenceTree::Seq OldRegion = Region;
14120 Region = CalleeRegion;
14122 SequencedSubexpression Sequenced(*this);
14123 Visit(CE->getCallee());
14125 Visit(CE->getCallee());
14129 Region = OtherRegion;
14133 Region = OldRegion;
14135 Tree.merge(CalleeRegion);
14136 Tree.merge(OtherRegion);
14154 return VisitCallExpr(CXXOCE);
14165 case OO_MinusEqual:
14167 case OO_SlashEqual:
14168 case OO_PercentEqual:
14169 case OO_CaretEqual:
14172 case OO_LessLessEqual:
14173 case OO_GreaterGreaterEqual:
14174 SequencingKind = RHSBeforeLHS;
14178 case OO_GreaterGreater:
14184 SequencingKind = LHSBeforeRHS;
14188 SequencingKind = LHSBeforeRest;
14192 SequencingKind = NoSequencing;
14196 if (SequencingKind == NoSequencing)
14197 return VisitCallExpr(CXXOCE);
14200 SequencedSubexpression Sequenced(*
this);
14203 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14204 "Should only get there with C++17 and above!");
14205 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14206 "Should only get there with an overloaded binary operator"
14207 " or an overloaded call operator!");
14209 if (SequencingKind == LHSBeforeRest) {
14210 assert(CXXOCE->getOperator() == OO_Call &&
14211 "We should only have an overloaded call operator here!");
14220 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14221 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14222 SequenceTree::Seq OldRegion = Region;
14224 assert(CXXOCE->getNumArgs() >= 1 &&
14225 "An overloaded call operator must have at least one argument"
14226 " for the postfix-expression!");
14227 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14228 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14229 CXXOCE->getNumArgs() - 1);
14233 Region = PostfixExprRegion;
14234 SequencedSubexpression Sequenced(*this);
14235 Visit(PostfixExpr);
14239 Region = ArgsRegion;
14240 for (const Expr *Arg : Args)
14243 Region = OldRegion;
14244 Tree.merge(PostfixExprRegion);
14245 Tree.merge(ArgsRegion);
14247 assert(CXXOCE->getNumArgs() == 2 &&
14248 "Should only have two arguments here!");
14249 assert((SequencingKind == LHSBeforeRHS ||
14250 SequencingKind == RHSBeforeLHS) &&
14251 "Unexpected sequencing kind!");
14255 const Expr *E1 = CXXOCE->getArg(0);
14256 const Expr *E2 = CXXOCE->getArg(1);
14257 if (SequencingKind == RHSBeforeLHS)
14260 return VisitSequencedExpressions(E1, E2);
14267 SequencedSubexpression Sequenced(*
this);
14270 return VisitExpr(CCE);
14273 SequenceExpressionsInOrder(
14279 return VisitExpr(ILE);
14282 SequenceExpressionsInOrder(ILE->
inits());
14294 SequenceTree::Seq Parent = Region;
14295 for (
const Expr *E : ExpressionList) {
14298 Region = Tree.allocate(Parent);
14299 Elts.push_back(Region);
14305 for (
unsigned I = 0; I < Elts.size(); ++I)
14306 Tree.merge(Elts[I]);
14310SequenceChecker::UsageInfo::UsageInfo() =
default;
14314void Sema::CheckUnsequencedOperations(
const Expr *E) {
14315 SmallVector<const Expr *, 8> WorkList;
14316 WorkList.push_back(E);
14317 while (!WorkList.empty()) {
14318 const Expr *Item = WorkList.pop_back_val();
14319 SequenceChecker(*
this, Item, WorkList);
14324 bool IsConstexpr) {
14327 CheckImplicitConversions(E, CheckLoc);
14329 CheckUnsequencedOperations(E);
14331 CheckForIntOverflow(E);
14344 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14348 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14352 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14366 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14370 bool CheckParameterNames) {
14371 bool HasInvalidParm =
false;
14373 assert(Param &&
"null in a parameter list");
14382 if (!Param->isInvalidDecl() &&
14384 diag::err_typecheck_decl_incomplete_type) ||
14386 diag::err_abstract_type_in_decl,
14388 Param->setInvalidDecl();
14389 HasInvalidParm =
true;
14394 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14398 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14406 QualType PType = Param->getOriginalType();
14414 if (!Param->isInvalidDecl()) {
14415 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14416 if (!ClassDecl->isInvalidDecl() &&
14417 !ClassDecl->hasIrrelevantDestructor() &&
14418 !ClassDecl->isDependentContext() &&
14419 ClassDecl->isParamDestroyedInCallee()) {
14431 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14432 if (!Param->getType().isConstQualified())
14433 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14437 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14442 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14443 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14448 if (!Param->isInvalidDecl() &&
14449 Param->getOriginalType()->isWebAssemblyTableType()) {
14450 Param->setInvalidDecl();
14451 HasInvalidParm =
true;
14452 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14456 return HasInvalidParm;
14459std::optional<std::pair<
14468static std::pair<CharUnits, CharUnits>
14476 if (
Base->isVirtual()) {
14483 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14490 DerivedType =
Base->getType();
14493 return std::make_pair(BaseAlignment, Offset);
14497static std::optional<std::pair<CharUnits, CharUnits>>
14503 return std::nullopt;
14508 return std::nullopt;
14512 CharUnits Offset = EltSize * IdxRes->getExtValue();
14515 return std::make_pair(P->first, P->second + Offset);
14521 return std::make_pair(
14522 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14528std::optional<std::pair<
14536 case Stmt::CStyleCastExprClass:
14537 case Stmt::CXXStaticCastExprClass:
14538 case Stmt::ImplicitCastExprClass: {
14540 const Expr *From = CE->getSubExpr();
14541 switch (CE->getCastKind()) {
14546 case CK_UncheckedDerivedToBase:
14547 case CK_DerivedToBase: {
14557 case Stmt::ArraySubscriptExprClass: {
14562 case Stmt::DeclRefExprClass: {
14566 if (!VD->getType()->isReferenceType()) {
14568 if (VD->hasDependentAlignment())
14577 case Stmt::MemberExprClass: {
14579 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14583 std::optional<std::pair<CharUnits, CharUnits>> P;
14592 return std::make_pair(P->first,
14595 case Stmt::UnaryOperatorClass: {
14605 case Stmt::BinaryOperatorClass: {
14617 return std::nullopt;
14622std::optional<std::pair<
14631 case Stmt::CStyleCastExprClass:
14632 case Stmt::CXXStaticCastExprClass:
14633 case Stmt::ImplicitCastExprClass: {
14635 const Expr *From = CE->getSubExpr();
14636 switch (CE->getCastKind()) {
14641 case CK_ArrayToPointerDecay:
14643 case CK_UncheckedDerivedToBase:
14644 case CK_DerivedToBase: {
14654 case Stmt::CXXThisExprClass: {
14659 case Stmt::UnaryOperatorClass: {
14665 case Stmt::BinaryOperatorClass: {
14674 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14675 std::swap(LHS, RHS);
14685 return std::nullopt;
14690 std::optional<std::pair<CharUnits, CharUnits>> P =
14694 return P->first.alignmentAtOffset(P->second);
14712 if (!DestPtr)
return;
14718 if (DestAlign.
isOne())
return;
14722 if (!SrcPtr)
return;
14733 if (SrcAlign >= DestAlign)
return;
14738 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14742void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14744 bool AllowOnePastEnd,
bool IndexNegated) {
14753 const Type *EffectiveType =
14757 Context.getAsConstantArrayType(BaseExpr->
getType());
14760 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14762 const Type *BaseType =
14764 bool IsUnboundedArray =
14766 Context, StrictFlexArraysLevel,
14769 (!IsUnboundedArray && BaseType->isDependentType()))
14777 if (IndexNegated) {
14778 index.setIsUnsigned(
false);
14782 if (IsUnboundedArray) {
14785 if (
index.isUnsigned() || !
index.isNegative()) {
14787 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14789 if (
index.getBitWidth() < AddrBits)
14791 std::optional<CharUnits> ElemCharUnits =
14792 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14795 if (!ElemCharUnits || ElemCharUnits->isZero())
14797 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
14802 if (
index.getActiveBits() <= AddrBits) {
14804 llvm::APInt Product(
index);
14806 Product = Product.umul_ov(ElemBytes, Overflow);
14807 if (!Overflow && Product.getActiveBits() <= AddrBits)
14813 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14814 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14816 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14817 MaxElems = MaxElems.udiv(ElemBytes);
14820 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14821 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14827 <<
toString(index, 10,
true) << AddrBits
14828 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14831 << (
unsigned)MaxElems.getLimitedValue(~0U)
14834 const NamedDecl *ND =
nullptr;
14836 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14838 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14840 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14841 ND = ME->getMemberDecl();
14845 PDiag(diag::note_array_declared_here) << ND);
14850 if (index.isUnsigned() || !index.isNegative()) {
14860 llvm::APInt size = ArrayTy->
getSize();
14862 if (BaseType != EffectiveType) {
14870 if (!ptrarith_typesize)
14871 ptrarith_typesize =
Context.getCharWidth();
14873 if (ptrarith_typesize != array_typesize) {
14875 uint64_t ratio = array_typesize / ptrarith_typesize;
14879 if (ptrarith_typesize * ratio == array_typesize)
14880 size *= llvm::APInt(size.getBitWidth(), ratio);
14884 if (size.getBitWidth() > index.getBitWidth())
14885 index = index.zext(size.getBitWidth());
14886 else if (size.getBitWidth() < index.getBitWidth())
14887 size = size.zext(index.getBitWidth());
14893 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
14900 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
14902 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
14903 SourceLocation IndexLoc =
14905 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
14910 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
14911 : diag::warn_ptr_arith_exceeds_bounds;
14912 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
14913 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
14920 unsigned DiagID = diag::warn_array_index_precedes_bounds;
14922 DiagID = diag::warn_ptr_arith_precedes_bounds;
14923 if (index.isNegative()) index = -index;
14931 const NamedDecl *ND =
nullptr;
14933 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14935 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14937 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14938 ND = ME->getMemberDecl();
14942 PDiag(diag::note_array_declared_here) << ND);
14945void Sema::CheckArrayAccess(
const Expr *
expr) {
14946 int AllowOnePastEnd = 0;
14948 expr =
expr->IgnoreParenImpCasts();
14949 switch (
expr->getStmtClass()) {
14950 case Stmt::ArraySubscriptExprClass: {
14953 AllowOnePastEnd > 0);
14957 case Stmt::MemberExprClass: {
14961 case Stmt::ArraySectionExprClass: {
14967 nullptr, AllowOnePastEnd > 0);
14970 case Stmt::UnaryOperatorClass: {
14986 case Stmt::ConditionalOperatorClass: {
14988 if (
const Expr *lhs = cond->
getLHS())
14989 CheckArrayAccess(lhs);
14990 if (
const Expr *rhs = cond->
getRHS())
14991 CheckArrayAccess(rhs);
14994 case Stmt::CXXOperatorCallExprClass: {
14996 for (
const auto *Arg : OCE->arguments())
14997 CheckArrayAccess(Arg);
15007 Expr *RHS,
bool isProperty) {
15019 S.
Diag(Loc, diag::warn_arc_literal_assign)
15021 << (isProperty ? 0 : 1)
15029 Expr *RHS,
bool isProperty) {
15032 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15033 S.
Diag(Loc, diag::warn_arc_retained_assign)
15035 << (isProperty ? 0 : 1)
15039 RHS =
cast->getSubExpr();
15081 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15110 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15111 Diag(Loc, diag::warn_arc_retained_property_assign)
15115 RHS =
cast->getSubExpr();
15138 bool StmtLineInvalid;
15139 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15141 if (StmtLineInvalid)
15144 bool BodyLineInvalid;
15145 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15147 if (BodyLineInvalid)
15151 if (StmtLine != BodyLine)
15166 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15175 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15179 const Stmt *PossibleBody) {
15185 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15186 StmtLoc = FS->getRParenLoc();
15187 Body = FS->getBody();
15188 DiagID = diag::warn_empty_for_body;
15189 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15190 StmtLoc = WS->getRParenLoc();
15191 Body = WS->getBody();
15192 DiagID = diag::warn_empty_while_body;
15197 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15221 if (!ProbableTypo) {
15222 bool BodyColInvalid;
15223 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15225 if (BodyColInvalid)
15228 bool StmtColInvalid;
15231 if (StmtColInvalid)
15234 if (BodyCol > StmtCol)
15235 ProbableTypo =
true;
15238 if (ProbableTypo) {
15240 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15248 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15260 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15262 RHSExpr = CE->
getArg(0);
15263 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15264 CXXSCE && CXXSCE->isXValue())
15265 RHSExpr = CXXSCE->getSubExpr();
15269 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15270 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15273 if (LHSDeclRef && RHSDeclRef) {
15280 auto D =
Diag(OpLoc, diag::warn_self_move)
15296 const Expr *LHSBase = LHSExpr;
15297 const Expr *RHSBase = RHSExpr;
15298 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15299 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15300 if (!LHSME || !RHSME)
15303 while (LHSME && RHSME) {
15310 LHSME = dyn_cast<MemberExpr>(LHSBase);
15311 RHSME = dyn_cast<MemberExpr>(RHSBase);
15314 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15315 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15316 if (LHSDeclRef && RHSDeclRef) {
15323 Diag(OpLoc, diag::warn_self_move)
15330 Diag(OpLoc, diag::warn_self_move)
15354 bool AreUnionMembers =
false) {
15358 assert(((Field1Parent->isStructureOrClassType() &&
15359 Field2Parent->isStructureOrClassType()) ||
15360 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15361 "Can't evaluate layout compatibility between a struct field and a "
15363 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15364 (AreUnionMembers && Field1Parent->isUnionType())) &&
15365 "AreUnionMembers should be 'true' for union fields (only).");
15379 if (Bits1 != Bits2)
15383 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15384 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15387 if (!AreUnionMembers &&
15399 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15400 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15402 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15403 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15408 return isLayoutCompatible(C, F1, F2);
15419 for (
auto *Field1 : RD1->
fields()) {
15420 auto I = UnmatchedFields.begin();
15421 auto E = UnmatchedFields.end();
15423 for ( ; I != E; ++I) {
15425 bool Result = UnmatchedFields.erase(*I);
15435 return UnmatchedFields.empty();
15461 if (
C.hasSameType(T1, T2))
15470 if (TC1 == Type::Enum)
15472 if (TC1 == Type::Record) {
15491 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15522 const ValueDecl **VD, uint64_t *MagicValue,
15523 bool isConstantEvaluated) {
15531 case Stmt::UnaryOperatorClass: {
15540 case Stmt::DeclRefExprClass: {
15546 case Stmt::IntegerLiteralClass: {
15548 llvm::APInt MagicValueAPInt = IL->
getValue();
15549 if (MagicValueAPInt.getActiveBits() <= 64) {
15550 *MagicValue = MagicValueAPInt.getZExtValue();
15556 case Stmt::BinaryConditionalOperatorClass:
15557 case Stmt::ConditionalOperatorClass: {
15562 isConstantEvaluated)) {
15572 case Stmt::BinaryOperatorClass: {
15575 TypeExpr = BO->
getRHS();
15605 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15608 bool isConstantEvaluated) {
15609 FoundWrongKind =
false;
15614 uint64_t MagicValue;
15616 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15620 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15621 if (I->getArgumentKind() != ArgumentKind) {
15622 FoundWrongKind =
true;
15625 TypeInfo.Type = I->getMatchingCType();
15626 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15627 TypeInfo.MustBeNull = I->getMustBeNull();
15638 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15639 if (I == MagicValues->end())
15648 bool LayoutCompatible,
15650 if (!TypeTagForDatatypeMagicValues)
15651 TypeTagForDatatypeMagicValues.reset(
15652 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15655 (*TypeTagForDatatypeMagicValues)[Magic] =
15671 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15672 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15673 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15674 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15677void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15680 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
15681 bool IsPointerAttr = Attr->getIsPointer();
15684 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
15685 if (TypeTagIdxAST >= ExprArgs.size()) {
15686 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15687 << 0 << Attr->getTypeTagIdx().getSourceIndex();
15690 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15691 bool FoundWrongKind;
15694 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15696 if (FoundWrongKind)
15698 diag::warn_type_tag_for_datatype_wrong_kind)
15704 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
15705 if (ArgumentIdxAST >= ExprArgs.size()) {
15706 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15707 << 1 << Attr->getArgumentIdx().getSourceIndex();
15710 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15711 if (IsPointerAttr) {
15713 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15714 if (ICE->getType()->isVoidPointerType() &&
15715 ICE->getCastKind() == CK_BitCast)
15716 ArgumentExpr = ICE->getSubExpr();
15718 QualType ArgumentType = ArgumentExpr->
getType();
15724 if (TypeInfo.MustBeNull) {
15729 diag::warn_type_safety_null_pointer_required)
15737 QualType RequiredType = TypeInfo.Type;
15739 RequiredType =
Context.getPointerType(RequiredType);
15741 bool mismatch =
false;
15742 if (!TypeInfo.LayoutCompatible) {
15743 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
15764 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15765 << ArgumentType << ArgumentKind
15766 << TypeInfo.LayoutCompatible << RequiredType
15784 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15792 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
15798 auto &MisalignedMembersForExpr =
15800 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15801 if (MA != MisalignedMembersForExpr.end() &&
15802 (
T->isDependentType() ||
T->isIntegerType() ||
15803 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
15805 T->getPointeeType()) <= MA->Alignment))))
15806 MisalignedMembersForExpr.erase(MA);
15815 const auto *ME = dyn_cast<MemberExpr>(E);
15827 bool AnyIsPacked =
false;
15829 QualType BaseType = ME->getBase()->getType();
15830 if (BaseType->isDependentType())
15834 auto *RD = BaseType->castAsRecordDecl();
15839 auto *FD = dyn_cast<FieldDecl>(MD);
15845 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15846 ReverseMemberChain.push_back(FD);
15849 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15851 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15858 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15869 if (ExpectedAlignment.
isOne())
15874 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15875 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
15879 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
15883 if (DRE && !TopME->
isArrow()) {
15886 CompleteObjectAlignment =
15887 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
15891 if (Offset % ExpectedAlignment != 0 ||
15894 CompleteObjectAlignment < ExpectedAlignment) {
15905 for (
FieldDecl *FDI : ReverseMemberChain) {
15906 if (FDI->hasAttr<PackedAttr>() ||
15907 FDI->getParent()->hasAttr<PackedAttr>()) {
15909 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
15915 assert(FD &&
"We did not find a packed FieldDecl!");
15916 Action(E, FD->
getParent(), FD, Alignment);
15920void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
15921 using namespace std::placeholders;
15924 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
15960bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
15961 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15974 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
15975 TheCall->
setType(VecTy0->getElementType());
15988 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16005 assert(!Args.empty() &&
"Should have at least one argument.");
16007 Expr *Arg0 = Args.front();
16010 auto EmitError = [&](
Expr *ArgI) {
16012 diag::err_typecheck_call_different_arg_types)
16013 << Arg0->
getType() << ArgI->getType();
16018 for (
Expr *ArgI : Args.drop_front())
16029 for (
Expr *ArgI : Args.drop_front()) {
16030 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16033 VecI->getElementType()) ||
16034 Vec0->getNumElements() != VecI->getNumElements()) {
16043std::optional<QualType>
16047 return std::nullopt;
16051 return std::nullopt;
16054 for (
int I = 0; I < 2; ++I) {
16058 return std::nullopt;
16059 Args[I] = Converted.
get();
16066 return std::nullopt;
16069 return std::nullopt;
16071 TheCall->
setArg(0, Args[0]);
16072 TheCall->
setArg(1, Args[1]);
16083 TheCall->
getArg(1), Loc) ||
16085 TheCall->
getArg(2), Loc))
16089 for (
int I = 0; I < 3; ++I) {
16094 Args[I] = Converted.
get();
16097 int ArgOrdinal = 1;
16098 for (
Expr *Arg : Args) {
16100 ArgTyRestr, ArgOrdinal++))
16107 for (
int I = 0; I < 3; ++I)
16108 TheCall->
setArg(I, Args[I]);
16114bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16126bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16135 diag::err_builtin_invalid_arg_type)
16136 << 1 << 2 << 1 << 1 << TyArg;
16150 Expr *Matrix = MatrixArg.
get();
16152 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16155 << 1 << 3 << 0 << 0
16162 QualType ResultType =
Context.getConstantMatrixType(
16163 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16166 TheCall->
setType(ResultType);
16169 TheCall->
setArg(0, Matrix);
16174static std::optional<unsigned>
16182 uint64_t
Dim =
Value->getZExtValue();
16201 unsigned PtrArgIdx = 0;
16202 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16203 Expr *RowsExpr = TheCall->
getArg(1);
16204 Expr *ColumnsExpr = TheCall->
getArg(2);
16205 Expr *StrideExpr = TheCall->
getArg(3);
16207 bool ArgError =
false;
16214 PtrExpr = PtrConv.
get();
16215 TheCall->
setArg(0, PtrExpr);
16222 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16223 QualType ElementTy;
16226 << PtrArgIdx + 1 << 0 << 5 << 0
16230 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16234 << PtrArgIdx + 1 << 0 << 5
16241 auto ApplyArgumentConversions = [
this](Expr *E) {
16250 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16252 RowsExpr = RowsConv.
get();
16253 TheCall->
setArg(1, RowsExpr);
16255 RowsExpr =
nullptr;
16257 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16259 ColumnsExpr = ColumnsConv.
get();
16260 TheCall->
setArg(2, ColumnsExpr);
16262 ColumnsExpr =
nullptr;
16273 std::optional<unsigned> MaybeRows;
16277 std::optional<unsigned> MaybeColumns;
16282 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16285 StrideExpr = StrideConv.
get();
16286 TheCall->
setArg(3, StrideExpr);
16289 if (std::optional<llvm::APSInt>
Value =
16292 if (Stride < *MaybeRows) {
16294 diag::err_builtin_matrix_stride_too_small);
16300 if (ArgError || !MaybeRows || !MaybeColumns)
16304 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16313 unsigned PtrArgIdx = 1;
16314 Expr *MatrixExpr = TheCall->
getArg(0);
16315 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16316 Expr *StrideExpr = TheCall->
getArg(2);
16318 bool ArgError =
false;
16324 MatrixExpr = MatrixConv.
get();
16325 TheCall->
setArg(0, MatrixExpr);
16332 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16335 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16343 PtrExpr = PtrConv.
get();
16344 TheCall->
setArg(1, PtrExpr);
16352 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16355 << PtrArgIdx + 1 << 0 << 5 << 0
16359 QualType ElementTy = PtrTy->getPointeeType();
16361 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16366 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16368 diag::err_builtin_matrix_pointer_arg_mismatch)
16369 << ElementTy << MatrixTy->getElementType();
16384 StrideExpr = StrideConv.
get();
16385 TheCall->
setArg(2, StrideExpr);
16390 if (std::optional<llvm::APSInt>
Value =
16393 if (Stride < MatrixTy->getNumRows()) {
16395 diag::err_builtin_matrix_stride_too_small);
16415 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16420 llvm::StringSet<> CalleeTCBs;
16421 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16422 CalleeTCBs.insert(A->getTCBName());
16423 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16424 CalleeTCBs.insert(A->getTCBName());
16428 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16429 StringRef CallerTCB = A->getTCBName();
16430 if (CalleeTCBs.count(CallerTCB) == 0) {
16431 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16432 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
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 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 builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
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 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 CFIUncheckedCalleeChange AdjustingCFIUncheckedCallee(QualType From, QualType To)
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 bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static ExprResult BuiltinTriviallyRelocate(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 void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos)
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 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 bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
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 ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
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 IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
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 bool IsEnumConstOrFromMacro(Sema &S, const 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 ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
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 void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
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 DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
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 ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
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 void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
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 checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
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 ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
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 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 BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
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.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
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.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
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
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) 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 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
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.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
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
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 getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
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...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
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 ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
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,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
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.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
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.
MutableArrayRef< 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 isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
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.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
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
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 getEndLoc() const
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...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
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.
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.
ConditionalOperator - The ?
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.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
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.
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Expr * getOperand() 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 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.
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 getBeginLoc() const
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.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
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.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
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.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
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...
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.
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 isFlexibleArrayMemberLike(const 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 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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
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.
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.
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.
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 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.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
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.
UnresolvedSetImpl::iterator iterator
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
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.
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.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
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)
PointerAuthQualifier getPointerAuth() const
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.
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.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
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.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
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 CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
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)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
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(const TargetInfo &TI, 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 DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
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...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
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 checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
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...
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.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
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....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
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...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
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)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
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
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)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool AddingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function without the cfi_unchecked_callee attribut...
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 BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
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...
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
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
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.
EltwiseBuiltinArgTyRestriction
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,...
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.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
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 IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
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
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
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 PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
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 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...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
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.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FomatStringIn...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
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.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
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,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
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...
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.
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.
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.
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
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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 TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
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.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
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 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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
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...
RecordDecl * castAsRecordDecl() const
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,...
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
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.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
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.
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
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
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 ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) 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
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ 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 LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(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.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ 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...
@ Success
Annotation was successful.
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.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ 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.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
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())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
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
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.
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.