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)
6874 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
6890bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6894 llvm::SmallBitVector &CheckedVarArgs) {
6895 FormatStringInfo FSI;
6899 return CheckFormatArguments(
6900 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
6905bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
6909 llvm::SmallBitVector &CheckedVarArgs) {
6910 FormatStringInfo FSI;
6914 return CheckFormatArguments(Args, FSI.ArgPassingKind,
6915 Format->getFormatString(), FSI.FormatIdx,
6917 CallType, Loc, Range, CheckedVarArgs);
6925 unsigned format_idx,
unsigned firstDataArg,
6929 llvm::SmallBitVector &CheckedVarArgs) {
6931 if (format_idx >= Args.size()) {
6932 Diag(Loc, diag::warn_missing_format_string) <<
Range;
6936 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6950 UncoveredArgHandler UncoveredArg;
6952 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
6953 firstDataArg,
Type, CallType,
6954 true, CheckedVarArgs, UncoveredArg,
6955 llvm::APSInt(64,
false) = 0);
6958 if (UncoveredArg.hasUncoveredArg()) {
6959 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6960 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6961 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6964 if (CT != SLCT_NotALiteral)
6966 return CT == SLCT_CheckedLiteral;
6977 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
6984 if (Args.size() == firstDataArg) {
6985 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(),
9127 if (ReferenceFormatString ==
nullptr) {
9128 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9129 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9130 inFunctionCall, CallType, CheckedVarArgs,
9140 Type, ReferenceFormatString, FExpr->getFormatString(),
9141 inFunctionCall ?
nullptr : Args[format_idx]);
9144 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9145 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9146 CallType, CheckedVarArgs, UncoveredArg);
9167 FormatStringLiteral RefLit = AuthoritativeFormatString;
9168 FormatStringLiteral TestLit = TestedFormatString;
9170 bool DiagAtStringLiteral;
9171 if (FunctionCallArg) {
9172 Arg = FunctionCallArg;
9173 DiagAtStringLiteral =
false;
9175 Arg = TestedFormatString;
9176 DiagAtStringLiteral =
true;
9178 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9179 AuthoritativeFormatString,
Type,
9180 IsObjC,
true, RefArgs) &&
9181 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9182 DiagAtStringLiteral, FmtArgs)) {
9184 TestedFormatString, FmtArgs, Arg,
9185 DiagAtStringLiteral);
9199 FormatStringLiteral RefLit = Str;
9203 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9212 bool HadError =
false;
9213 auto Iter = Args.begin();
9214 auto End = Args.end();
9215 while (Iter != End) {
9216 const auto &FirstInGroup = *Iter;
9218 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9220 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9229 const char *Str = StrRef.data();
9232 assert(
T &&
"String literal not of constant array type!");
9233 size_t TypeSize =
T->getZExtSize();
9234 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9245 switch (AbsFunction) {
9249 case Builtin::BI__builtin_abs:
9250 return Builtin::BI__builtin_labs;
9251 case Builtin::BI__builtin_labs:
9252 return Builtin::BI__builtin_llabs;
9253 case Builtin::BI__builtin_llabs:
9256 case Builtin::BI__builtin_fabsf:
9257 return Builtin::BI__builtin_fabs;
9258 case Builtin::BI__builtin_fabs:
9259 return Builtin::BI__builtin_fabsl;
9260 case Builtin::BI__builtin_fabsl:
9263 case Builtin::BI__builtin_cabsf:
9264 return Builtin::BI__builtin_cabs;
9265 case Builtin::BI__builtin_cabs:
9266 return Builtin::BI__builtin_cabsl;
9267 case Builtin::BI__builtin_cabsl:
9270 case Builtin::BIabs:
9271 return Builtin::BIlabs;
9272 case Builtin::BIlabs:
9273 return Builtin::BIllabs;
9274 case Builtin::BIllabs:
9277 case Builtin::BIfabsf:
9278 return Builtin::BIfabs;
9279 case Builtin::BIfabs:
9280 return Builtin::BIfabsl;
9281 case Builtin::BIfabsl:
9284 case Builtin::BIcabsf:
9285 return Builtin::BIcabs;
9286 case Builtin::BIcabs:
9287 return Builtin::BIcabsl;
9288 case Builtin::BIcabsl:
9317 unsigned AbsFunctionKind) {
9318 unsigned BestKind = 0;
9319 uint64_t ArgSize = Context.getTypeSize(ArgType);
9320 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9323 if (Context.getTypeSize(ParamType) >= ArgSize) {
9326 else if (Context.hasSameType(ParamType, ArgType)) {
9342 if (
T->isIntegralOrEnumerationType())
9344 if (
T->isRealFloatingType())
9346 if (
T->isAnyComplexType())
9349 llvm_unreachable(
"Type not integer, floating, or complex");
9356 switch (ValueKind) {
9361 case Builtin::BI__builtin_fabsf:
9362 case Builtin::BI__builtin_fabs:
9363 case Builtin::BI__builtin_fabsl:
9364 case Builtin::BI__builtin_cabsf:
9365 case Builtin::BI__builtin_cabs:
9366 case Builtin::BI__builtin_cabsl:
9367 return Builtin::BI__builtin_abs;
9368 case Builtin::BIfabsf:
9369 case Builtin::BIfabs:
9370 case Builtin::BIfabsl:
9371 case Builtin::BIcabsf:
9372 case Builtin::BIcabs:
9373 case Builtin::BIcabsl:
9374 return Builtin::BIabs;
9380 case Builtin::BI__builtin_abs:
9381 case Builtin::BI__builtin_labs:
9382 case Builtin::BI__builtin_llabs:
9383 case Builtin::BI__builtin_cabsf:
9384 case Builtin::BI__builtin_cabs:
9385 case Builtin::BI__builtin_cabsl:
9386 return Builtin::BI__builtin_fabsf;
9387 case Builtin::BIabs:
9388 case Builtin::BIlabs:
9389 case Builtin::BIllabs:
9390 case Builtin::BIcabsf:
9391 case Builtin::BIcabs:
9392 case Builtin::BIcabsl:
9393 return Builtin::BIfabsf;
9399 case Builtin::BI__builtin_abs:
9400 case Builtin::BI__builtin_labs:
9401 case Builtin::BI__builtin_llabs:
9402 case Builtin::BI__builtin_fabsf:
9403 case Builtin::BI__builtin_fabs:
9404 case Builtin::BI__builtin_fabsl:
9405 return Builtin::BI__builtin_cabsf;
9406 case Builtin::BIabs:
9407 case Builtin::BIlabs:
9408 case Builtin::BIllabs:
9409 case Builtin::BIfabsf:
9410 case Builtin::BIfabs:
9411 case Builtin::BIfabsl:
9412 return Builtin::BIcabsf;
9415 llvm_unreachable(
"Unable to convert function");
9426 case Builtin::BI__builtin_abs:
9427 case Builtin::BI__builtin_fabs:
9428 case Builtin::BI__builtin_fabsf:
9429 case Builtin::BI__builtin_fabsl:
9430 case Builtin::BI__builtin_labs:
9431 case Builtin::BI__builtin_llabs:
9432 case Builtin::BI__builtin_cabs:
9433 case Builtin::BI__builtin_cabsf:
9434 case Builtin::BI__builtin_cabsl:
9435 case Builtin::BIabs:
9436 case Builtin::BIlabs:
9437 case Builtin::BIllabs:
9438 case Builtin::BIfabs:
9439 case Builtin::BIfabsf:
9440 case Builtin::BIfabsl:
9441 case Builtin::BIcabs:
9442 case Builtin::BIcabsf:
9443 case Builtin::BIcabsl:
9446 llvm_unreachable(
"Unknown Builtin type");
9452 unsigned AbsKind,
QualType ArgType) {
9453 bool EmitHeaderHint =
true;
9454 const char *HeaderName =
nullptr;
9455 std::string FunctionName;
9456 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9457 FunctionName =
"std::abs";
9458 if (ArgType->isIntegralOrEnumerationType()) {
9459 HeaderName =
"cstdlib";
9460 }
else if (ArgType->isRealFloatingType()) {
9461 HeaderName =
"cmath";
9463 llvm_unreachable(
"Invalid Type");
9472 for (
const auto *I : R) {
9475 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9477 FDecl = dyn_cast<FunctionDecl>(I);
9492 EmitHeaderHint =
false;
9510 EmitHeaderHint =
false;
9514 }
else if (!R.
empty()) {
9520 S.
Diag(Loc, diag::note_replace_abs_function)
9526 if (!EmitHeaderHint)
9529 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9533template <std::
size_t StrLen>
9535 const char (&Str)[StrLen]) {
9548 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9549 return llvm::is_contained(names, calleeName);
9554 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9555 "__builtin_nanf16",
"__builtin_nanf128"});
9557 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9558 "__builtin_inff16",
"__builtin_inff128"});
9560 llvm_unreachable(
"unknown MathCheck");
9564 if (FDecl->
getName() !=
"infinity")
9567 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9569 if (RDecl->
getName() !=
"numeric_limits")
9586 if (FPO.getNoHonorNaNs() &&
9589 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9590 << 1 << 0 <<
Call->getSourceRange();
9594 if (FPO.getNoHonorInfs() &&
9598 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9599 << 0 << 0 <<
Call->getSourceRange();
9603void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9605 if (
Call->getNumArgs() != 1)
9610 if (AbsKind == 0 && !IsStdAbs)
9613 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9614 QualType ParamType =
Call->getArg(0)->getType();
9619 std::string FunctionName =
9620 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9621 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9622 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9651 if (ArgValueKind == ParamValueKind) {
9652 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9656 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9657 << FDecl << ArgType << ParamType;
9659 if (NewAbsKind == 0)
9663 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9672 if (NewAbsKind == 0)
9675 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9676 << FDecl << ParamValueKind << ArgValueKind;
9679 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9685 if (!
Call || !FDecl)
return;
9689 if (
Call->getExprLoc().isMacroID())
return;
9692 if (
Call->getNumArgs() != 2)
return;
9695 if (!ArgList)
return;
9696 if (ArgList->size() != 1)
return;
9699 const auto& TA = ArgList->
get(0);
9701 QualType ArgType = TA.getAsType();
9705 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
9706 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
9707 if (!MTE)
return false;
9708 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9709 if (!
Num)
return false;
9710 if (
Num->getValue() != 0)
return false;
9714 const Expr *FirstArg =
Call->getArg(0);
9715 const Expr *SecondArg =
Call->getArg(1);
9716 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9717 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9720 if (IsFirstArgZero == IsSecondArgZero)
return;
9725 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9727 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9728 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9731 SourceRange RemovalRange;
9732 if (IsFirstArgZero) {
9733 RemovalRange = SourceRange(FirstRange.
getBegin(),
9740 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9755 const auto *Size = dyn_cast<BinaryOperator>(E);
9760 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9764 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9765 << SizeRange << FnName;
9766 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9771 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9782 bool &IsContained) {
9784 const Type *Ty =
T->getBaseElementTypeUnsafe();
9785 IsContained =
false;
9798 for (
auto *FD : RD->
fields()) {
9811 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
9812 if (Unary->getKind() == UETT_SizeOf)
9821 if (!
SizeOf->isArgumentType())
9822 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9829 return SizeOf->getTypeOfArgument();
9835struct SearchNonTrivialToInitializeField
9838 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
9840 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
9843 SourceLocation SL) {
9844 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9845 asDerived().visitArray(PDIK, AT, SL);
9849 Super::visitWithKind(PDIK, FT, SL);
9852 void visitARCStrong(QualType FT, SourceLocation SL) {
9855 void visitARCWeak(QualType FT, SourceLocation SL) {
9858 void visitStruct(QualType FT, SourceLocation SL) {
9863 const ArrayType *AT, SourceLocation SL) {
9864 visit(getContext().getBaseElementType(AT), SL);
9866 void visitTrivial(QualType FT, SourceLocation SL) {}
9868 static void diag(QualType RT,
const Expr *E, Sema &S) {
9869 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
9878struct SearchNonTrivialToCopyField
9880 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
9882 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
9885 SourceLocation SL) {
9886 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9887 asDerived().visitArray(PCK, AT, SL);
9891 Super::visitWithKind(PCK, FT, SL);
9894 void visitARCStrong(QualType FT, SourceLocation SL) {
9897 void visitARCWeak(QualType FT, SourceLocation SL) {
9900 void visitPtrAuth(QualType FT, SourceLocation SL) {
9903 void visitStruct(QualType FT, SourceLocation SL) {
9908 SourceLocation SL) {
9909 visit(getContext().getBaseElementType(AT), SL);
9912 SourceLocation SL) {}
9913 void visitTrivial(QualType FT, SourceLocation SL) {}
9914 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
9916 static void diag(QualType RT,
const Expr *E, Sema &S) {
9917 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
9932 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
9933 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
9957 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
9959 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
9960 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
9966 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
9969 const Expr *SizeArg =
9970 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
9972 auto isLiteralZero = [](
const Expr *E) {
9982 if (isLiteralZero(SizeArg) &&
9989 if (BId == Builtin::BIbzero ||
9992 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
9993 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
9994 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
9995 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
9996 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10004 if (BId == Builtin::BImemset &&
10008 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10009 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10014void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10021 unsigned ExpectedNumArgs =
10022 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10023 if (
Call->getNumArgs() < ExpectedNumArgs)
10026 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10027 BId == Builtin::BIstrndup ? 1 : 2);
10029 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10030 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10033 Call->getBeginLoc(),
Call->getRParenLoc()))
10042 llvm::FoldingSetNodeID SizeOfArgID;
10047 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10048 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10051 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10052 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10053 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10055 QualType DestTy = Dest->
getType();
10056 QualType PointeeTy;
10057 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10070 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10074 if (SizeOfArgID == llvm::FoldingSetNodeID())
10076 llvm::FoldingSetNodeID DestID;
10078 if (DestID == SizeOfArgID) {
10081 unsigned ActionIdx = 0;
10082 StringRef ReadableName = FnName->
getName();
10084 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10085 if (UnaryOp->getOpcode() == UO_AddrOf)
10094 SourceLocation SL = SizeOfArg->
getExprLoc();
10099 if (
SM.isMacroArgExpansion(SL)) {
10101 SL =
SM.getSpellingLoc(SL);
10102 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10104 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10109 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10116 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10127 if (SizeOfArgTy != QualType()) {
10129 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10131 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10132 << FnName << SizeOfArgTy << ArgIdx
10139 PointeeTy = DestTy;
10142 if (PointeeTy == QualType())
10147 if (
const CXXRecordDecl *ContainedRD =
10150 unsigned OperationType = 0;
10151 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10154 if (ArgIdx != 0 || IsCmp) {
10155 if (BId == Builtin::BImemcpy)
10157 else if(BId == Builtin::BImemmove)
10164 PDiag(diag::warn_dyn_class_memaccess)
10165 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10166 << IsContained << ContainedRD << OperationType
10167 <<
Call->getCallee()->getSourceRange());
10169 BId != Builtin::BImemset)
10172 PDiag(diag::warn_arc_object_memaccess)
10173 << ArgIdx << FnName << PointeeTy
10174 <<
Call->getCallee()->getSourceRange());
10181 bool NonTriviallyCopyableCXXRecord =
10185 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10188 PDiag(diag::warn_cstruct_memaccess)
10189 << ArgIdx << FnName << PointeeTy << 0);
10190 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10191 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10192 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10196 PDiag(diag::warn_cxxstruct_memaccess)
10197 << FnName << PointeeTy);
10198 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10201 PDiag(diag::warn_cstruct_memaccess)
10202 << ArgIdx << FnName << PointeeTy << 1);
10203 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10204 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10205 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10209 PDiag(diag::warn_cxxstruct_memaccess)
10210 << FnName << PointeeTy);
10219 PDiag(diag::note_bad_memaccess_silence)
10255 if (CAT->getZExtSize() <= 1)
10263void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10267 unsigned NumArgs =
Call->getNumArgs();
10268 if ((NumArgs != 3) && (NumArgs != 4))
10273 const Expr *CompareWithSrc =
nullptr;
10276 Call->getBeginLoc(),
Call->getRParenLoc()))
10281 CompareWithSrc = Ex;
10284 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10285 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10286 SizeCall->getNumArgs() == 1)
10291 if (!CompareWithSrc)
10298 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10302 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10303 if (!CompareWithSrcDRE ||
10307 const Expr *OriginalSizeArg =
Call->getArg(2);
10308 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10315 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10319 SmallString<128> sizeString;
10320 llvm::raw_svector_ostream
OS(sizeString);
10325 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10332 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10333 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10334 return D1->getDecl() == D2->getDecl();
10339 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10348void Sema::CheckStrncatArguments(
const CallExpr *CE,
10363 unsigned PatternType = 0;
10371 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10372 if (BE->getOpcode() == BO_Sub) {
10373 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10374 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10385 if (PatternType == 0)
10394 if (
SM.isMacroArgExpansion(SL)) {
10395 SL =
SM.getSpellingLoc(SL);
10396 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10401 QualType DstTy = DstArg->
getType();
10404 if (!isKnownSizeArray) {
10405 if (PatternType == 1)
10406 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10408 Diag(SL, diag::warn_strncat_src_size) << SR;
10412 if (PatternType == 1)
10413 Diag(SL, diag::warn_strncat_large_size) << SR;
10415 Diag(SL, diag::warn_strncat_src_size) << SR;
10417 SmallString<128> sizeString;
10418 llvm::raw_svector_ostream
OS(sizeString);
10426 Diag(SL, diag::note_strncat_wrong_size)
10431void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10440void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10442 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10443 const Decl *D = Lvalue->getDecl();
10444 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10445 if (!DD->getType()->isReferenceType())
10446 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10450 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10451 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10452 Lvalue->getMemberDecl());
10455void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10457 const auto *Lambda = dyn_cast<LambdaExpr>(
10462 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10463 << CalleeName << 2 ;
10466void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10468 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10469 if (Var ==
nullptr)
10473 << CalleeName << 0 << Var;
10476void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10479 llvm::raw_svector_ostream
OS(SizeString);
10482 if (Kind == clang::CK_BitCast &&
10483 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10485 if (Kind == clang::CK_IntegralToPointer &&
10487 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10490 switch (
Cast->getCastKind()) {
10491 case clang::CK_BitCast:
10492 case clang::CK_IntegralToPointer:
10493 case clang::CK_FunctionToPointerDecay:
10502 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10503 << CalleeName << 0 <<
OS.str();
10507void Sema::CheckFreeArguments(
const CallExpr *E) {
10508 const std::string CalleeName =
10513 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10515 case UnaryOperator::Opcode::UO_AddrOf:
10516 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10517 case UnaryOperator::Opcode::UO_Plus:
10518 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10523 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10525 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10527 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10528 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10529 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10535 << CalleeName << 1 ;
10540 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10541 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10545Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10554 Diag(ReturnLoc, diag::warn_null_ret)
10564 if (Op == OO_New || Op == OO_Array_New) {
10565 const FunctionProtoType *Proto
10569 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10575 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10580 if (
Context.getTargetInfo().getTriple().isPPC64())
10592 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10593 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10595 return FPLiteral && FPCast;
10598 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10604 llvm::APFloat TargetC = FPLiteral->
getValue();
10605 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10606 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10610 Diag(Loc, diag::warn_float_compare_literal)
10611 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10624 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10625 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10626 if (DRL->getDecl() == DRR->getDecl())
10634 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10635 if (FLL->isExact())
10637 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10638 if (FLR->isExact())
10642 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10643 CL &&
CL->getBuiltinCallee())
10646 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10647 CR && CR->getBuiltinCallee())
10651 Diag(Loc, diag::warn_floatingpoint_eq)
10672 IntRange(
unsigned Width,
bool NonNegative)
10673 : Width(Width), NonNegative(NonNegative) {}
10676 unsigned valueBits()
const {
10677 return NonNegative ? Width : Width - 1;
10681 static IntRange forBoolType() {
10682 return IntRange(1,
true);
10686 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
10687 return forValueOfCanonicalType(
C,
10692 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
10695 if (
const auto *VT = dyn_cast<VectorType>(
T))
10696 T = VT->getElementType().getTypePtr();
10697 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10698 T = CT->getElementType().getTypePtr();
10699 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10700 T = AT->getValueType().getTypePtr();
10702 if (!
C.getLangOpts().CPlusPlus) {
10705 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10710 if (
Enum->isFixed()) {
10711 return IntRange(
C.getIntWidth(QualType(
T, 0)),
10712 !
Enum->getIntegerType()->isSignedIntegerType());
10715 unsigned NumPositive =
Enum->getNumPositiveBits();
10716 unsigned NumNegative =
Enum->getNumNegativeBits();
10718 if (NumNegative == 0)
10719 return IntRange(NumPositive,
true);
10721 return IntRange(std::max(NumPositive + 1, NumNegative),
10725 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10726 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10739 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
10742 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10743 T = VT->getElementType().getTypePtr();
10744 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
10745 T = CT->getElementType().getTypePtr();
10746 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10747 T = AT->getValueType().getTypePtr();
10749 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10751 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10752 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10761 static IntRange join(IntRange L, IntRange R) {
10762 bool Unsigned = L.NonNegative && R.NonNegative;
10763 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10764 L.NonNegative && R.NonNegative);
10768 static IntRange bit_and(IntRange L, IntRange R) {
10769 unsigned Bits = std::max(L.Width, R.Width);
10770 bool NonNegative =
false;
10771 if (L.NonNegative) {
10772 Bits = std::min(Bits, L.Width);
10773 NonNegative =
true;
10775 if (R.NonNegative) {
10776 Bits = std::min(Bits, R.Width);
10777 NonNegative =
true;
10779 return IntRange(Bits, NonNegative);
10783 static IntRange sum(IntRange L, IntRange R) {
10784 bool Unsigned = L.NonNegative && R.NonNegative;
10785 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10790 static IntRange difference(IntRange L, IntRange R) {
10794 bool CanWiden = !L.NonNegative || !R.NonNegative;
10795 bool Unsigned = L.NonNegative && R.Width == 0;
10796 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10802 static IntRange product(IntRange L, IntRange R) {
10806 bool CanWiden = !L.NonNegative && !R.NonNegative;
10807 bool Unsigned = L.NonNegative && R.NonNegative;
10808 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10813 static IntRange rem(IntRange L, IntRange R) {
10817 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10825 if (value.isSigned() && value.isNegative())
10826 return IntRange(value.getSignificantBits(),
false);
10828 if (value.getBitWidth() > MaxWidth)
10829 value = value.trunc(MaxWidth);
10833 return IntRange(value.getActiveBits(),
true);
10837 if (result.
isInt())
10844 R = IntRange::join(R, El);
10852 return IntRange::join(R, I);
10867 Ty = AtomicRHS->getValueType();
10886 bool InConstantContext,
10887 bool Approximate) {
10898 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
10899 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
10903 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
10905 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
10906 CE->getCastKind() == CK_BooleanToSignedIntegral;
10909 if (!isIntegerCast)
10910 return OutputTypeRange;
10913 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
10914 InConstantContext, Approximate);
10916 return std::nullopt;
10919 if (SubRange->Width >= OutputTypeRange.Width)
10920 return OutputTypeRange;
10924 return IntRange(SubRange->Width,
10925 SubRange->NonNegative || OutputTypeRange.NonNegative);
10928 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
10931 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
10933 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
10934 InConstantContext, Approximate);
10939 Expr *TrueExpr = CO->getTrueExpr();
10941 return std::nullopt;
10943 std::optional<IntRange> L =
10946 return std::nullopt;
10948 Expr *FalseExpr = CO->getFalseExpr();
10950 return std::nullopt;
10952 std::optional<IntRange> R =
10955 return std::nullopt;
10957 return IntRange::join(*L, *R);
10960 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
10961 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
10963 switch (BO->getOpcode()) {
10965 llvm_unreachable(
"builtin <=> should have class type");
10976 return IntRange::forBoolType();
11005 Combine = IntRange::bit_and;
11013 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11014 if (I->getValue() == 1) {
11015 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11016 return IntRange(R.Width,
true);
11026 case BO_ShrAssign: {
11028 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11030 return std::nullopt;
11034 if (std::optional<llvm::APSInt> shift =
11035 BO->getRHS()->getIntegerConstantExpr(
C)) {
11036 if (shift->isNonNegative()) {
11037 if (shift->uge(L->Width))
11038 L->Width = (L->NonNegative ? 0 : 1);
11040 L->Width -= shift->getZExtValue();
11054 Combine = IntRange::sum;
11058 if (BO->getLHS()->getType()->isPointerType())
11061 Combine = IntRange::difference;
11066 Combine = IntRange::product;
11075 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11077 return std::nullopt;
11080 if (std::optional<llvm::APSInt> divisor =
11081 BO->getRHS()->getIntegerConstantExpr(
C)) {
11082 unsigned log2 = divisor->logBase2();
11083 if (
log2 >= L->Width)
11084 L->Width = (L->NonNegative ? 0 : 1);
11086 L->Width = std::min(L->Width -
log2, MaxWidth);
11094 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11096 return std::nullopt;
11098 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11102 Combine = IntRange::rem;
11114 unsigned opWidth =
C.getIntWidth(
T);
11116 InConstantContext, Approximate);
11118 return std::nullopt;
11121 InConstantContext, Approximate);
11123 return std::nullopt;
11125 IntRange
C = Combine(*L, *R);
11126 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11127 C.Width = std::min(
C.Width, MaxWidth);
11131 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11132 switch (UO->getOpcode()) {
11135 return IntRange::forBoolType();
11149 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11152 return std::nullopt;
11157 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11167 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11170 return std::nullopt;
11175 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11185 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11186 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11190 return IntRange(BitField->getBitWidthValue(),
11191 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11194 return std::nullopt;
11200 bool InConstantContext,
11201 bool Approximate) {
11210 const llvm::fltSemantics &Src,
11211 const llvm::fltSemantics &Tgt) {
11212 llvm::APFloat truncated = value;
11215 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11216 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11218 return truncated.bitwiseIsEqual(value);
11227 const llvm::fltSemantics &Src,
11228 const llvm::fltSemantics &Tgt) {
11245 bool IsListInit =
false);
11260 return MacroName !=
"YES" && MacroName !=
"NO" &&
11261 MacroName !=
"true" && MacroName !=
"false";
11269 (!E->
getType()->isSignedIntegerType() ||
11284struct PromotedRange {
11286 llvm::APSInt PromotedMin;
11288 llvm::APSInt PromotedMax;
11290 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11292 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11293 else if (R.Width >= BitWidth && !
Unsigned) {
11297 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11298 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11300 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11301 .extOrTrunc(BitWidth);
11302 PromotedMin.setIsUnsigned(
Unsigned);
11304 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11305 .extOrTrunc(BitWidth);
11306 PromotedMax.setIsUnsigned(
Unsigned);
11311 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11321 InRangeFlag = 0x40,
11324 Min =
LE | InRangeFlag,
11325 InRange = InRangeFlag,
11326 Max =
GE | InRangeFlag,
11329 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11334 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11335 Value.isUnsigned() == PromotedMin.isUnsigned());
11336 if (!isContiguous()) {
11337 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11338 if (
Value.isMinValue())
return Min;
11339 if (
Value.isMaxValue())
return Max;
11340 if (
Value >= PromotedMin)
return InRange;
11341 if (
Value <= PromotedMax)
return InRange;
11345 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11346 case -1:
return Less;
11347 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11349 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11350 case -1:
return InRange;
11351 case 0:
return Max;
11356 llvm_unreachable(
"impossible compare result");
11359 static std::optional<StringRef>
11361 if (Op == BO_Cmp) {
11363 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11365 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11366 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11367 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11368 return std::nullopt;
11375 }
else if (Op == BO_NE) {
11379 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11386 if (Op == BO_GE || Op == BO_LE)
11387 std::swap(TrueFlag, FalseFlag);
11390 return StringRef(
"true");
11392 return StringRef(
"false");
11393 return std::nullopt;
11400 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11401 if (ICE->getCastKind() != CK_IntegralCast &&
11402 ICE->getCastKind() != CK_NoOp)
11404 E = ICE->getSubExpr();
11413 enum ConstantValueKind {
11418 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11419 return BL->getValue() ? ConstantValueKind::LiteralTrue
11420 : ConstantValueKind::LiteralFalse;
11421 return ConstantValueKind::Miscellaneous;
11426 const llvm::APSInt &
Value,
11427 bool RhsConstant) {
11449 if (!OtherValueRange)
11454 OtherT = AT->getValueType();
11455 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11459 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11465 bool OtherIsBooleanDespiteType =
11467 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11468 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11472 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11473 Value.isUnsigned());
11474 auto Cmp = OtherPromotedValueRange.compare(
Value);
11475 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11481 bool TautologicalTypeCompare =
false;
11483 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11484 Value.isUnsigned());
11485 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11488 TautologicalTypeCompare =
true;
11496 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11505 bool InRange = Cmp & PromotedRange::InRangeFlag;
11511 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11512 Other->getType()->isUnsignedIntegerOrEnumerationType())
11513 TautologicalTypeCompare =
true;
11518 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11519 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11523 llvm::raw_svector_ostream OS(PrettySourceValue);
11525 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11526 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11528 OS << (BL->getValue() ?
"YES" :
"NO");
11533 if (!TautologicalTypeCompare) {
11535 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11541 if (IsObjCSignedCharBool) {
11543 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11544 << OS.str() << *Result);
11551 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11555 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11556 : diag::warn_tautological_bool_compare)
11558 << OtherIsBooleanDespiteType << *Result
11565 ? diag::warn_unsigned_enum_always_true_comparison
11566 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11567 : diag::warn_unsigned_always_true_comparison)
11568 : diag::warn_tautological_constant_compare;
11571 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11604 if (
T->isIntegralType(S.
Context)) {
11605 std::optional<llvm::APSInt> RHSValue =
11607 std::optional<llvm::APSInt> LHSValue =
11611 if (RHSValue && LHSValue)
11615 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11617 const bool RhsConstant = (
bool)RHSValue;
11618 Expr *Const = RhsConstant ? RHS : LHS;
11620 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11629 if (!
T->hasUnsignedIntegerRepresentation()) {
11643 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11645 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11651 Expr *signedOperand, *unsignedOperand;
11654 "unsigned comparison between two signed integer expressions?");
11655 signedOperand = LHS;
11656 unsignedOperand = RHS;
11658 signedOperand = RHS;
11659 unsignedOperand = LHS;
11665 std::optional<IntRange> signedRange =
11677 if (signedRange->NonNegative)
11689 if (!unsignedRange)
11694 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11696 if (unsignedRange->Width < comparisonWidth)
11701 S.
PDiag(diag::warn_mixed_sign_comparison)
11720 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11725 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11726 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11727 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11728 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11729 << BitfieldEnumDecl;
11736 Init->isValueDependent() ||
11737 Init->isTypeDependent())
11740 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11750 const PreferredTypeAttr *PTAttr =
nullptr;
11752 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11754 ED = PTAttr->getType()->getAsEnumDecl();
11762 bool SignedEnum = ED->getNumNegativeBits() > 0;
11769 unsigned DiagID = 0;
11770 if (SignedEnum && !SignedBitfield) {
11773 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11775 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11776 }
else if (SignedBitfield && !SignedEnum &&
11777 ED->getNumPositiveBits() == FieldWidth) {
11780 ? diag::warn_signed_bitfield_enum_conversion
11781 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11784 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11789 << SignedEnum << TypeRange;
11791 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11798 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11799 ED->getNumNegativeBits())
11800 : ED->getNumPositiveBits();
11803 if (BitsNeeded > FieldWidth) {
11807 ? diag::warn_bitfield_too_small_for_enum
11808 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11809 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11813 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11821 llvm::APSInt
Value = Result.Val.getInt();
11823 unsigned OriginalWidth =
Value.getBitWidth();
11829 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11830 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11837 if (!
Value.isSigned() ||
Value.isNegative())
11838 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11839 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11840 OriginalWidth =
Value.getSignificantBits();
11842 if (OriginalWidth <= FieldWidth)
11846 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11850 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11851 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11855 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11857 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11858 ? diag::warn_impcast_single_bit_bitield_precision_constant
11859 : diag::warn_impcast_bitfield_precision_constant)
11860 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11861 <<
Init->getSourceRange();
11893 bool PruneControlFlow =
false) {
11900 if (
T.hasAddressSpace())
11902 if (PruneControlFlow) {
11916 bool PruneControlFlow =
false) {
11923 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
11928 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
11929 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
11934 llvm::APFloat
Value(0.0);
11940 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
11945 diag::warn_impcast_float_integer, PruneWarnings);
11948 bool isExact =
false;
11951 T->hasUnsignedIntegerRepresentation());
11952 llvm::APFloat::opStatus Result =
Value.convertToInteger(
11953 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
11961 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
11962 precision = (precision * 59 + 195) / 196;
11963 Value.toString(PrettySourceValue, precision);
11967 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
11968 << PrettySourceValue);
11971 if (Result == llvm::APFloat::opOK && isExact) {
11972 if (IsLiteral)
return;
11973 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
11979 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
11982 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
11983 : diag::warn_impcast_float_to_integer_out_of_range,
11986 unsigned DiagID = 0;
11989 DiagID = diag::warn_impcast_literal_float_to_integer;
11990 }
else if (IntegerValue == 0) {
11991 if (
Value.isZero()) {
11993 diag::warn_impcast_float_integer, PruneWarnings);
11996 DiagID = diag::warn_impcast_float_to_integer_zero;
11998 if (IntegerValue.isUnsigned()) {
11999 if (!IntegerValue.isMaxValue()) {
12001 diag::warn_impcast_float_integer, PruneWarnings);
12004 if (!IntegerValue.isMaxSignedValue() &&
12005 !IntegerValue.isMinSignedValue()) {
12007 diag::warn_impcast_float_integer, PruneWarnings);
12011 DiagID = diag::warn_impcast_float_to_integer;
12016 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12018 IntegerValue.toString(PrettyTargetValue);
12020 if (PruneWarnings) {
12023 << E->
getType() <<
T.getUnqualifiedType()
12024 << PrettySourceValue << PrettyTargetValue
12028 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12037 "Must be compound assignment operation");
12048 ->getComputationResultType()
12055 if (ResultBT->isInteger())
12057 E->
getExprLoc(), diag::warn_impcast_float_integer);
12059 if (!ResultBT->isFloatingPoint())
12068 diag::warn_impcast_float_result_precision);
12073 if (!Range.Width)
return "0";
12075 llvm::APSInt ValueInRange =
Value;
12076 ValueInRange.setIsSigned(!Range.NonNegative);
12077 ValueInRange = ValueInRange.trunc(Range.Width);
12078 return toString(ValueInRange, 10);
12088 const Type *Source =
12090 if (
Target->isDependentType())
12093 const auto *FloatCandidateBT =
12094 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12095 const Type *BoolCandidateType = ToBool ?
Target : Source;
12098 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12103 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12109 S, TheCall->
getArg(I - 1),
false));
12111 S, TheCall->
getArg(I + 1),
false));
12116 diag::warn_impcast_floating_point_to_bool);
12131 if (!IsGNUNullExpr && !HasNullPtrType)
12135 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12136 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12139 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12152 if (IsGNUNullExpr && Loc.
isMacroID()) {
12155 if (MacroName ==
"NULL")
12163 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12177 const char FirstLiteralCharacter =
12179 if (FirstLiteralCharacter ==
'0')
12185 if (CC.
isValid() &&
T->isCharType()) {
12186 const char FirstContextCharacter =
12188 if (FirstContextCharacter ==
'{')
12196 const auto *IL = dyn_cast<IntegerLiteral>(E);
12198 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12199 if (UO->getOpcode() == UO_Minus)
12200 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12211 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12215 if (Opc == BO_Shl) {
12218 if (LHS && LHS->getValue() == 0)
12219 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12221 RHS->getValue().isNonNegative() &&
12223 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12224 << (Result.Val.getInt() != 0);
12226 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12233 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12238 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12239 (RHS->getValue() == 0 || RHS->getValue() == 1))
12242 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12243 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12251 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12256 llvm::APSInt
Value(32);
12257 Value = Result.Val.getInt();
12258 bool IsASCII =
Value <= 0x7F;
12259 bool IsBMP =
Value <= 0xD7FF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12260 bool ConversionPreservesSemantics =
12261 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12263 if (!ConversionPreservesSemantics) {
12264 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12265 const llvm::APSInt &
Value) {
12266 if (
T->isChar8Type())
12267 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12268 if (
T->isChar16Type())
12269 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12270 assert(
T->isChar32Type());
12271 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12274 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12283 LosesPrecision ? diag::warn_impcast_unicode_precision
12284 : diag::warn_impcast_unicode_char_type);
12298 From = MaybePointee;
12305 if (FromFn->getCFIUncheckedCalleeAttr() &&
12306 !ToFn->getCFIUncheckedCalleeAttr())
12308 if (!FromFn->getCFIUncheckedCalleeAttr() &&
12309 ToFn->getCFIUncheckedCalleeAttr())
12317 From =
Context.getCanonicalType(From);
12318 To =
Context.getCanonicalType(To);
12319 return ::AdjustingCFIUncheckedCallee(From, To) ==
Discarding;
12323 From =
Context.getCanonicalType(From);
12324 To =
Context.getCanonicalType(To);
12325 return ::AdjustingCFIUncheckedCallee(From, To) ==
Adding;
12329 bool *ICContext,
bool IsListInit) {
12334 if (Source ==
Target)
return;
12335 if (
Target->isDependentType())
return;
12345 if (Source->isAtomicType())
12349 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12355 diag::warn_impcast_string_literal_to_bool);
12361 diag::warn_impcast_objective_c_literal_to_bool);
12363 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12373 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12376 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12378 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12387 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12389 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12394 if (
Target->isSveVLSBuiltinType() &&
12401 if (
Target->isRVVVLSBuiltinType() &&
12411 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12418 diag::warn_hlsl_impcast_vector_truncation);
12430 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12431 Target = VecTy->getElementType().getTypePtr();
12441 ? diag::err_impcast_complex_scalar
12442 : diag::warn_impcast_complex_scalar);
12449 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12455 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12458 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12460 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12502 else if (Order < 0) {
12512 if (TargetBT && TargetBT->
isInteger()) {
12539 diag::warn_impcast_floating_point_to_bool);
12547 if (Source->isFixedPointType()) {
12548 if (
Target->isUnsaturatedFixedPointType()) {
12552 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12553 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12554 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12557 PDiag(diag::warn_impcast_fixed_point_range)
12558 <<
Value.toString() <<
T
12564 }
else if (
Target->isIntegerType()) {
12568 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12571 llvm::APSInt IntResult = FXResult.convertToInt(
12572 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12577 PDiag(diag::warn_impcast_fixed_point_range)
12578 << FXResult.toString() <<
T
12585 }
else if (
Target->isUnsaturatedFixedPointType()) {
12586 if (Source->isIntegerType()) {
12593 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12598 PDiag(diag::warn_impcast_fixed_point_range)
12619 unsigned int SourcePrecision =
SourceRange->Width;
12623 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12626 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12627 SourcePrecision > TargetPrecision) {
12629 if (std::optional<llvm::APSInt> SourceInt =
12634 llvm::APFloat TargetFloatValue(
12636 llvm::APFloat::opStatus ConversionStatus =
12637 TargetFloatValue.convertFromAPInt(
12639 llvm::APFloat::rmNearestTiesToEven);
12641 if (ConversionStatus != llvm::APFloat::opOK) {
12643 SourceInt->toString(PrettySourceValue, 10);
12645 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12649 PDiag(diag::warn_impcast_integer_float_precision_constant)
12650 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12656 diag::warn_impcast_integer_float_precision);
12665 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12670 if (
Target->isBooleanType())
12674 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12678 if (!Source->isIntegerType() || !
Target->isIntegerType())
12683 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12686 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
12689 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12694 if (!LikelySourceRange)
12697 IntRange SourceTypeRange =
12698 IntRange::forTargetOfCanonicalType(
Context, Source);
12699 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12701 if (LikelySourceRange->Width > TargetRange.Width) {
12707 llvm::APSInt
Value(32);
12717 PDiag(diag::warn_impcast_integer_precision_constant)
12718 << PrettySourceValue << PrettyTargetValue
12728 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12729 if (UO->getOpcode() == UO_Minus)
12731 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12734 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
12738 diag::warn_impcast_integer_precision);
12741 if (TargetRange.Width > SourceTypeRange.Width) {
12742 if (
auto *UO = dyn_cast<UnaryOperator>(E))
12743 if (UO->getOpcode() == UO_Minus)
12744 if (Source->isUnsignedIntegerType()) {
12745 if (
Target->isUnsignedIntegerType())
12747 diag::warn_impcast_high_order_zero_bits);
12748 if (
Target->isSignedIntegerType())
12750 diag::warn_impcast_nonnegative_result);
12754 if (TargetRange.Width == LikelySourceRange->Width &&
12755 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12756 Source->isSignedIntegerType()) {
12770 PDiag(diag::warn_impcast_integer_precision_constant)
12771 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12781 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12782 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12783 LikelySourceRange->Width == TargetRange.Width))) {
12787 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12789 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
12793 unsigned DiagID = diag::warn_impcast_integer_sign;
12801 DiagID = diag::warn_impcast_integer_sign_conditional;
12818 Source =
Context.getCanonicalType(SourceType).getTypePtr();
12820 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
12821 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
12822 if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
12823 TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
12824 SourceEnum != TargetEnum) {
12829 diag::warn_impcast_different_enum_types);
12843 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
12856 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
12857 TrueExpr = BCO->getCommon();
12859 bool Suspicious =
false;
12863 if (
T->isBooleanType())
12868 if (!Suspicious)
return;
12871 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12878 Suspicious =
false;
12883 E->
getType(), CC, &Suspicious);
12900struct AnalyzeImplicitConversionsWorkItem {
12909 bool ExtraCheckForImplicitConversion,
12912 WorkList.push_back({E, CC,
false});
12914 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
12921 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
12923 Expr *OrigE = Item.E;
12942 Expr *SourceExpr = E;
12947 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
12948 if (
auto *Src = OVE->getSourceExpr())
12951 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
12952 if (UO->getOpcode() == UO_Not &&
12953 UO->getSubExpr()->isKnownToHaveBooleanValue())
12954 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
12958 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
12959 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
12960 BO->getLHS()->isKnownToHaveBooleanValue() &&
12961 BO->getRHS()->isKnownToHaveBooleanValue() &&
12962 BO->getLHS()->HasSideEffects(S.
Context) &&
12963 BO->getRHS()->HasSideEffects(S.
Context)) {
12974 if (SR.str() ==
"&" || SR.str() ==
"|") {
12976 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
12977 << (BO->getOpcode() == BO_And ?
"&" :
"|")
12980 BO->getOperatorLoc(),
12981 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
12982 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
12984 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13002 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13008 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13023 for (
auto *SE : POE->semantics())
13024 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13025 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13029 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13030 E = CE->getSubExpr();
13036 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13037 if (InitListE->getNumInits() == 1) {
13038 E = InitListE->getInit(0);
13045 WorkList.push_back({E, CC, IsListInit});
13049 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13050 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13054 if (OutArgE->isInOut())
13055 WorkList.push_back(
13056 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13057 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13063 if (BO->isComparisonOp())
13067 if (BO->getOpcode() == BO_Assign)
13070 if (BO->isAssignmentOp())
13086 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13088 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13092 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13093 if (ChildExpr == CSE->getOperand())
13099 if (IsLogicalAndOperator &&
13104 WorkList.push_back({ChildExpr, CC, IsListInit});
13118 if (
U->getOpcode() == UO_LNot) {
13120 }
else if (
U->getOpcode() != UO_AddrOf) {
13121 if (
U->getSubExpr()->getType()->isAtomicType())
13122 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13123 diag::warn_atomic_implicit_seq_cst);
13134 WorkList.push_back({OrigE, CC, IsListInit});
13135 while (!WorkList.empty())
13147 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13150 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13151 if (!M->getMemberDecl()->getType()->isReferenceType())
13153 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13154 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13156 FD =
Call->getDirectCallee();
13165 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13179 if (
SM.isMacroBodyExpansion(Loc))
13181 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13205 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13206 : diag::warn_this_bool_conversion;
13211 bool IsAddressOf =
false;
13213 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13214 if (UO->getOpcode() != UO_AddrOf)
13216 IsAddressOf =
true;
13217 E = UO->getSubExpr();
13221 unsigned DiagID = IsCompare
13222 ? diag::warn_address_of_reference_null_compare
13223 : diag::warn_address_of_reference_bool_conversion;
13231 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13234 llvm::raw_string_ostream S(Str);
13236 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13237 : diag::warn_cast_nonnull_to_bool;
13240 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13245 if (
auto *Callee =
Call->getDirectCallee()) {
13246 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13247 ComplainAboutNonnullParamOrCall(A);
13256 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13257 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13258 MRecordDecl && MRecordDecl->isLambda()) {
13261 << MRecordDecl->getSourceRange() << Range << IsEqual;
13271 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13272 D = M->getMemberDecl();
13280 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13283 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13284 ComplainAboutNonnullParamOrCall(A);
13288 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13292 auto ParamIter = llvm::find(FD->
parameters(), PV);
13294 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13298 ComplainAboutNonnullParamOrCall(
NonNull);
13303 if (ArgNo.getASTIndex() == ParamNo) {
13304 ComplainAboutNonnullParamOrCall(
NonNull);
13314 const bool IsArray =
T->isArrayType();
13315 const bool IsFunction =
T->isFunctionType();
13318 if (IsAddressOf && IsFunction) {
13323 if (!IsAddressOf && !IsFunction && !IsArray)
13328 llvm::raw_string_ostream S(Str);
13331 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13332 : diag::warn_impcast_pointer_to_bool;
13339 DiagType = AddressOf;
13340 else if (IsFunction)
13341 DiagType = FunctionPointer;
13343 DiagType = ArrayPointer;
13345 llvm_unreachable(
"Could not determine diagnostic.");
13347 << Range << IsEqual;
13360 if (ReturnType.
isNull())
13398 CheckArrayAccess(E);
13408void Sema::CheckForIntOverflow (
const Expr *E) {
13410 SmallVector<const Expr *, 2> Exprs(1, E);
13413 const Expr *OriginalE = Exprs.pop_back_val();
13421 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13422 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13425 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13426 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13427 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13429 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13430 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13431 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13432 Exprs.push_back(Temporary->getSubExpr());
13433 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13434 Exprs.push_back(Array->getIdx());
13435 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13436 Exprs.push_back(Compound->getInitializer());
13437 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13438 New &&
New->isArray()) {
13439 if (
auto ArraySize =
New->getArraySize())
13440 Exprs.push_back(*ArraySize);
13441 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13442 Exprs.push_back(MTE->getSubExpr());
13443 }
while (!Exprs.empty());
13451 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13458 class SequenceTree {
13460 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13461 unsigned Parent : 31;
13462 LLVM_PREFERRED_TYPE(
bool)
13463 unsigned Merged : 1;
13465 SmallVector<Value, 8> Values;
13471 friend class SequenceTree;
13475 explicit Seq(
unsigned N) : Index(N) {}
13478 Seq() : Index(0) {}
13481 SequenceTree() { Values.push_back(
Value(0)); }
13482 Seq root()
const {
return Seq(0); }
13487 Seq allocate(
Seq Parent) {
13488 Values.push_back(
Value(Parent.Index));
13489 return Seq(Values.size() - 1);
13493 void merge(
Seq S) {
13494 Values[S.Index].Merged =
true;
13500 bool isUnsequenced(
Seq Cur,
Seq Old) {
13501 unsigned C = representative(Cur.Index);
13502 unsigned Target = representative(Old.Index);
13506 C = Values[
C].Parent;
13513 unsigned representative(
unsigned K) {
13514 if (Values[K].Merged)
13516 return Values[K].Parent = representative(Values[K].Parent);
13522 using Object =
const NamedDecl *;
13536 UK_ModAsSideEffect,
13538 UK_Count = UK_ModAsSideEffect + 1
13544 const Expr *UsageExpr =
nullptr;
13545 SequenceTree::Seq
Seq;
13551 Usage Uses[UK_Count];
13554 bool Diagnosed =
false;
13558 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13566 UsageInfoMap UsageMap;
13569 SequenceTree::Seq Region;
13573 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13577 SmallVectorImpl<const Expr *> &WorkList;
13584 struct SequencedSubexpression {
13585 SequencedSubexpression(SequenceChecker &
Self)
13586 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13587 Self.ModAsSideEffect = &ModAsSideEffect;
13590 ~SequencedSubexpression() {
13591 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13595 UsageInfo &UI =
Self.UsageMap[M.first];
13596 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13597 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13598 SideEffectUsage = M.second;
13600 Self.ModAsSideEffect = OldModAsSideEffect;
13603 SequenceChecker &
Self;
13604 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13605 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13612 class EvaluationTracker {
13614 EvaluationTracker(SequenceChecker &
Self)
13616 Self.EvalTracker =
this;
13619 ~EvaluationTracker() {
13620 Self.EvalTracker = Prev;
13622 Prev->EvalOK &= EvalOK;
13625 bool evaluate(
const Expr *E,
bool &
Result) {
13630 Self.SemaRef.isConstantEvaluatedContext());
13635 SequenceChecker &
Self;
13636 EvaluationTracker *Prev;
13637 bool EvalOK =
true;
13638 } *EvalTracker =
nullptr;
13642 Object getObject(
const Expr *E,
bool Mod)
const {
13644 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13645 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13646 return getObject(UO->getSubExpr(), Mod);
13647 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13648 if (BO->getOpcode() == BO_Comma)
13649 return getObject(BO->getRHS(), Mod);
13650 if (Mod && BO->isAssignmentOp())
13651 return getObject(BO->getLHS(), Mod);
13652 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13655 return ME->getMemberDecl();
13656 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13665 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13667 Usage &U = UI.Uses[UK];
13668 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
13672 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13673 ModAsSideEffect->push_back(std::make_pair(O, U));
13675 U.UsageExpr = UsageExpr;
13685 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13686 UsageKind OtherKind,
bool IsModMod) {
13690 const Usage &U = UI.Uses[OtherKind];
13691 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
13694 const Expr *Mod = U.UsageExpr;
13695 const Expr *ModOrUse = UsageExpr;
13696 if (OtherKind == UK_Use)
13697 std::swap(Mod, ModOrUse);
13701 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13702 : diag::warn_unsequenced_mod_use)
13703 << O << SourceRange(ModOrUse->
getExprLoc()));
13704 UI.Diagnosed =
true;
13733 void notePreUse(Object O,
const Expr *UseExpr) {
13734 UsageInfo &UI = UsageMap[O];
13736 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13739 void notePostUse(Object O,
const Expr *UseExpr) {
13740 UsageInfo &UI = UsageMap[O];
13741 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13743 addUsage(O, UI, UseExpr, UK_Use);
13746 void notePreMod(Object O,
const Expr *ModExpr) {
13747 UsageInfo &UI = UsageMap[O];
13749 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13750 checkUsage(O, UI, ModExpr, UK_Use,
false);
13753 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13754 UsageInfo &UI = UsageMap[O];
13755 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13757 addUsage(O, UI, ModExpr, UK);
13761 SequenceChecker(Sema &S,
const Expr *E,
13762 SmallVectorImpl<const Expr *> &WorkList)
13763 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
13767 (void)this->WorkList;
13770 void VisitStmt(
const Stmt *S) {
13774 void VisitExpr(
const Expr *E) {
13776 Base::VisitStmt(E);
13779 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
13780 for (
auto *Sub : CSE->
children()) {
13781 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13796 void VisitCastExpr(
const CastExpr *E) {
13808 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13809 const Expr *SequencedAfter) {
13810 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
13811 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
13812 SequenceTree::Seq OldRegion = Region;
13815 SequencedSubexpression SeqBefore(*
this);
13816 Region = BeforeRegion;
13817 Visit(SequencedBefore);
13820 Region = AfterRegion;
13821 Visit(SequencedAfter);
13823 Region = OldRegion;
13825 Tree.merge(BeforeRegion);
13826 Tree.merge(AfterRegion);
13829 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
13834 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13841 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13842 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13843 void VisitBinPtrMem(
const BinaryOperator *BO) {
13848 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13855 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13856 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13857 void VisitBinShlShr(
const BinaryOperator *BO) {
13861 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13868 void VisitBinComma(
const BinaryOperator *BO) {
13873 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13876 void VisitBinAssign(
const BinaryOperator *BO) {
13877 SequenceTree::Seq RHSRegion;
13878 SequenceTree::Seq LHSRegion;
13880 RHSRegion = Tree.allocate(Region);
13881 LHSRegion = Tree.allocate(Region);
13883 RHSRegion = Region;
13884 LHSRegion = Region;
13886 SequenceTree::Seq OldRegion = Region;
13902 SequencedSubexpression SeqBefore(*
this);
13903 Region = RHSRegion;
13907 Region = LHSRegion;
13911 notePostUse(O, BO);
13915 Region = LHSRegion;
13919 notePostUse(O, BO);
13921 Region = RHSRegion;
13929 Region = OldRegion;
13933 : UK_ModAsSideEffect);
13935 Tree.merge(RHSRegion);
13936 Tree.merge(LHSRegion);
13940 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
13941 VisitBinAssign(CAO);
13944 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13945 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13946 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
13949 return VisitExpr(UO);
13957 : UK_ModAsSideEffect);
13960 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13961 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13962 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
13965 return VisitExpr(UO);
13969 notePostMod(O, UO, UK_ModAsSideEffect);
13972 void VisitBinLOr(
const BinaryOperator *BO) {
13978 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
13979 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
13980 SequenceTree::Seq OldRegion = Region;
13982 EvaluationTracker Eval(*
this);
13984 SequencedSubexpression Sequenced(*
this);
13985 Region = LHSRegion;
13992 bool EvalResult =
false;
13993 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13994 bool ShouldVisitRHS = !EvalOK || !EvalResult;
13995 if (ShouldVisitRHS) {
13996 Region = RHSRegion;
14000 Region = OldRegion;
14001 Tree.merge(LHSRegion);
14002 Tree.merge(RHSRegion);
14005 void VisitBinLAnd(
const BinaryOperator *BO) {
14011 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14012 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14013 SequenceTree::Seq OldRegion = Region;
14015 EvaluationTracker Eval(*
this);
14017 SequencedSubexpression Sequenced(*
this);
14018 Region = LHSRegion;
14024 bool EvalResult =
false;
14025 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14026 bool ShouldVisitRHS = !EvalOK || EvalResult;
14027 if (ShouldVisitRHS) {
14028 Region = RHSRegion;
14032 Region = OldRegion;
14033 Tree.merge(LHSRegion);
14034 Tree.merge(RHSRegion);
14037 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14042 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14058 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14059 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14060 SequenceTree::Seq OldRegion = Region;
14062 EvaluationTracker Eval(*
this);
14064 SequencedSubexpression Sequenced(*
this);
14065 Region = ConditionRegion;
14075 bool EvalResult =
false;
14076 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14077 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14078 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14079 if (ShouldVisitTrueExpr) {
14080 Region = TrueRegion;
14083 if (ShouldVisitFalseExpr) {
14084 Region = FalseRegion;
14088 Region = OldRegion;
14089 Tree.merge(ConditionRegion);
14090 Tree.merge(TrueRegion);
14091 Tree.merge(FalseRegion);
14094 void VisitCallExpr(
const CallExpr *CE) {
14106 SequencedSubexpression Sequenced(*
this);
14111 SequenceTree::Seq CalleeRegion;
14112 SequenceTree::Seq OtherRegion;
14113 if (SemaRef.getLangOpts().CPlusPlus17) {
14114 CalleeRegion = Tree.allocate(Region);
14115 OtherRegion = Tree.allocate(Region);
14117 CalleeRegion = Region;
14118 OtherRegion = Region;
14120 SequenceTree::Seq OldRegion = Region;
14123 Region = CalleeRegion;
14125 SequencedSubexpression Sequenced(*this);
14126 Visit(CE->getCallee());
14128 Visit(CE->getCallee());
14132 Region = OtherRegion;
14136 Region = OldRegion;
14138 Tree.merge(CalleeRegion);
14139 Tree.merge(OtherRegion);
14157 return VisitCallExpr(CXXOCE);
14168 case OO_MinusEqual:
14170 case OO_SlashEqual:
14171 case OO_PercentEqual:
14172 case OO_CaretEqual:
14175 case OO_LessLessEqual:
14176 case OO_GreaterGreaterEqual:
14177 SequencingKind = RHSBeforeLHS;
14181 case OO_GreaterGreater:
14187 SequencingKind = LHSBeforeRHS;
14191 SequencingKind = LHSBeforeRest;
14195 SequencingKind = NoSequencing;
14199 if (SequencingKind == NoSequencing)
14200 return VisitCallExpr(CXXOCE);
14203 SequencedSubexpression Sequenced(*
this);
14206 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14207 "Should only get there with C++17 and above!");
14208 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14209 "Should only get there with an overloaded binary operator"
14210 " or an overloaded call operator!");
14212 if (SequencingKind == LHSBeforeRest) {
14213 assert(CXXOCE->getOperator() == OO_Call &&
14214 "We should only have an overloaded call operator here!");
14223 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14224 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14225 SequenceTree::Seq OldRegion = Region;
14227 assert(CXXOCE->getNumArgs() >= 1 &&
14228 "An overloaded call operator must have at least one argument"
14229 " for the postfix-expression!");
14230 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14231 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14232 CXXOCE->getNumArgs() - 1);
14236 Region = PostfixExprRegion;
14237 SequencedSubexpression Sequenced(*this);
14238 Visit(PostfixExpr);
14242 Region = ArgsRegion;
14243 for (const Expr *Arg : Args)
14246 Region = OldRegion;
14247 Tree.merge(PostfixExprRegion);
14248 Tree.merge(ArgsRegion);
14250 assert(CXXOCE->getNumArgs() == 2 &&
14251 "Should only have two arguments here!");
14252 assert((SequencingKind == LHSBeforeRHS ||
14253 SequencingKind == RHSBeforeLHS) &&
14254 "Unexpected sequencing kind!");
14258 const Expr *E1 = CXXOCE->getArg(0);
14259 const Expr *E2 = CXXOCE->getArg(1);
14260 if (SequencingKind == RHSBeforeLHS)
14263 return VisitSequencedExpressions(E1, E2);
14270 SequencedSubexpression Sequenced(*
this);
14273 return VisitExpr(CCE);
14276 SequenceExpressionsInOrder(
14282 return VisitExpr(ILE);
14285 SequenceExpressionsInOrder(ILE->
inits());
14297 SequenceTree::Seq Parent = Region;
14298 for (
const Expr *E : ExpressionList) {
14301 Region = Tree.allocate(Parent);
14302 Elts.push_back(Region);
14308 for (
unsigned I = 0; I < Elts.size(); ++I)
14309 Tree.merge(Elts[I]);
14313SequenceChecker::UsageInfo::UsageInfo() =
default;
14317void Sema::CheckUnsequencedOperations(
const Expr *E) {
14318 SmallVector<const Expr *, 8> WorkList;
14319 WorkList.push_back(E);
14320 while (!WorkList.empty()) {
14321 const Expr *Item = WorkList.pop_back_val();
14322 SequenceChecker(*
this, Item, WorkList);
14327 bool IsConstexpr) {
14330 CheckImplicitConversions(E, CheckLoc);
14332 CheckUnsequencedOperations(E);
14334 CheckForIntOverflow(E);
14347 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14351 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14355 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14369 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14373 bool CheckParameterNames) {
14374 bool HasInvalidParm =
false;
14376 assert(Param &&
"null in a parameter list");
14385 if (!Param->isInvalidDecl() &&
14387 diag::err_typecheck_decl_incomplete_type) ||
14389 diag::err_abstract_type_in_decl,
14391 Param->setInvalidDecl();
14392 HasInvalidParm =
true;
14397 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14401 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14409 QualType PType = Param->getOriginalType();
14417 if (!Param->isInvalidDecl()) {
14418 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14419 if (!ClassDecl->isInvalidDecl() &&
14420 !ClassDecl->hasIrrelevantDestructor() &&
14421 !ClassDecl->isDependentContext() &&
14422 ClassDecl->isParamDestroyedInCallee()) {
14434 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14435 if (!Param->getType().isConstQualified())
14436 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14440 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14445 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14446 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14451 if (!Param->isInvalidDecl() &&
14452 Param->getOriginalType()->isWebAssemblyTableType()) {
14453 Param->setInvalidDecl();
14454 HasInvalidParm =
true;
14455 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14459 return HasInvalidParm;
14462std::optional<std::pair<
14471static std::pair<CharUnits, CharUnits>
14479 if (
Base->isVirtual()) {
14486 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14493 DerivedType =
Base->getType();
14496 return std::make_pair(BaseAlignment, Offset);
14500static std::optional<std::pair<CharUnits, CharUnits>>
14506 return std::nullopt;
14511 return std::nullopt;
14515 CharUnits Offset = EltSize * IdxRes->getExtValue();
14518 return std::make_pair(P->first, P->second + Offset);
14524 return std::make_pair(
14525 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14531std::optional<std::pair<
14539 case Stmt::CStyleCastExprClass:
14540 case Stmt::CXXStaticCastExprClass:
14541 case Stmt::ImplicitCastExprClass: {
14543 const Expr *From = CE->getSubExpr();
14544 switch (CE->getCastKind()) {
14549 case CK_UncheckedDerivedToBase:
14550 case CK_DerivedToBase: {
14560 case Stmt::ArraySubscriptExprClass: {
14565 case Stmt::DeclRefExprClass: {
14569 if (!VD->getType()->isReferenceType()) {
14571 if (VD->hasDependentAlignment())
14580 case Stmt::MemberExprClass: {
14582 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14586 std::optional<std::pair<CharUnits, CharUnits>> P;
14595 return std::make_pair(P->first,
14598 case Stmt::UnaryOperatorClass: {
14608 case Stmt::BinaryOperatorClass: {
14620 return std::nullopt;
14625std::optional<std::pair<
14634 case Stmt::CStyleCastExprClass:
14635 case Stmt::CXXStaticCastExprClass:
14636 case Stmt::ImplicitCastExprClass: {
14638 const Expr *From = CE->getSubExpr();
14639 switch (CE->getCastKind()) {
14644 case CK_ArrayToPointerDecay:
14646 case CK_UncheckedDerivedToBase:
14647 case CK_DerivedToBase: {
14657 case Stmt::CXXThisExprClass: {
14662 case Stmt::UnaryOperatorClass: {
14668 case Stmt::BinaryOperatorClass: {
14677 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14678 std::swap(LHS, RHS);
14688 return std::nullopt;
14693 std::optional<std::pair<CharUnits, CharUnits>> P =
14697 return P->first.alignmentAtOffset(P->second);
14715 if (!DestPtr)
return;
14721 if (DestAlign.
isOne())
return;
14725 if (!SrcPtr)
return;
14736 if (SrcAlign >= DestAlign)
return;
14741 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14745void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14747 bool AllowOnePastEnd,
bool IndexNegated) {
14756 const Type *EffectiveType =
14760 Context.getAsConstantArrayType(BaseExpr->
getType());
14763 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14765 const Type *BaseType =
14767 bool IsUnboundedArray =
14769 Context, StrictFlexArraysLevel,
14772 (!IsUnboundedArray && BaseType->isDependentType()))
14780 if (IndexNegated) {
14781 index.setIsUnsigned(
false);
14785 if (IsUnboundedArray) {
14788 if (
index.isUnsigned() || !
index.isNegative()) {
14790 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14792 if (
index.getBitWidth() < AddrBits)
14794 std::optional<CharUnits> ElemCharUnits =
14795 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14798 if (!ElemCharUnits || ElemCharUnits->isZero())
14800 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
14805 if (
index.getActiveBits() <= AddrBits) {
14807 llvm::APInt Product(
index);
14809 Product = Product.umul_ov(ElemBytes, Overflow);
14810 if (!Overflow && Product.getActiveBits() <= AddrBits)
14816 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14817 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14819 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14820 MaxElems = MaxElems.udiv(ElemBytes);
14823 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14824 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14830 <<
toString(index, 10,
true) << AddrBits
14831 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14834 << (
unsigned)MaxElems.getLimitedValue(~0U)
14837 const NamedDecl *ND =
nullptr;
14839 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14841 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14843 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14844 ND = ME->getMemberDecl();
14848 PDiag(diag::note_array_declared_here) << ND);
14853 if (index.isUnsigned() || !index.isNegative()) {
14863 llvm::APInt size = ArrayTy->
getSize();
14865 if (BaseType != EffectiveType) {
14873 if (!ptrarith_typesize)
14874 ptrarith_typesize =
Context.getCharWidth();
14876 if (ptrarith_typesize != array_typesize) {
14878 uint64_t ratio = array_typesize / ptrarith_typesize;
14882 if (ptrarith_typesize * ratio == array_typesize)
14883 size *= llvm::APInt(size.getBitWidth(), ratio);
14887 if (size.getBitWidth() > index.getBitWidth())
14888 index = index.zext(size.getBitWidth());
14889 else if (size.getBitWidth() < index.getBitWidth())
14890 size = size.zext(index.getBitWidth());
14896 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
14903 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
14905 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
14906 SourceLocation IndexLoc =
14908 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
14913 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
14914 : diag::warn_ptr_arith_exceeds_bounds;
14915 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
14916 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
14923 unsigned DiagID = diag::warn_array_index_precedes_bounds;
14925 DiagID = diag::warn_ptr_arith_precedes_bounds;
14926 if (index.isNegative()) index = -index;
14934 const NamedDecl *ND =
nullptr;
14936 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14938 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14940 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14941 ND = ME->getMemberDecl();
14945 PDiag(diag::note_array_declared_here) << ND);
14948void Sema::CheckArrayAccess(
const Expr *
expr) {
14949 int AllowOnePastEnd = 0;
14951 expr =
expr->IgnoreParenImpCasts();
14952 switch (
expr->getStmtClass()) {
14953 case Stmt::ArraySubscriptExprClass: {
14956 AllowOnePastEnd > 0);
14960 case Stmt::MemberExprClass: {
14964 case Stmt::ArraySectionExprClass: {
14970 nullptr, AllowOnePastEnd > 0);
14973 case Stmt::UnaryOperatorClass: {
14989 case Stmt::ConditionalOperatorClass: {
14991 if (
const Expr *lhs = cond->
getLHS())
14992 CheckArrayAccess(lhs);
14993 if (
const Expr *rhs = cond->
getRHS())
14994 CheckArrayAccess(rhs);
14997 case Stmt::CXXOperatorCallExprClass: {
14999 for (
const auto *Arg : OCE->arguments())
15000 CheckArrayAccess(Arg);
15010 Expr *RHS,
bool isProperty) {
15022 S.
Diag(Loc, diag::warn_arc_literal_assign)
15024 << (isProperty ? 0 : 1)
15032 Expr *RHS,
bool isProperty) {
15035 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15036 S.
Diag(Loc, diag::warn_arc_retained_assign)
15038 << (isProperty ? 0 : 1)
15042 RHS =
cast->getSubExpr();
15084 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15113 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15114 Diag(Loc, diag::warn_arc_retained_property_assign)
15118 RHS =
cast->getSubExpr();
15141 bool StmtLineInvalid;
15142 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15144 if (StmtLineInvalid)
15147 bool BodyLineInvalid;
15148 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15150 if (BodyLineInvalid)
15154 if (StmtLine != BodyLine)
15169 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15178 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15182 const Stmt *PossibleBody) {
15188 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15189 StmtLoc = FS->getRParenLoc();
15190 Body = FS->getBody();
15191 DiagID = diag::warn_empty_for_body;
15192 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15193 StmtLoc = WS->getRParenLoc();
15194 Body = WS->getBody();
15195 DiagID = diag::warn_empty_while_body;
15200 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15224 if (!ProbableTypo) {
15225 bool BodyColInvalid;
15226 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15228 if (BodyColInvalid)
15231 bool StmtColInvalid;
15234 if (StmtColInvalid)
15237 if (BodyCol > StmtCol)
15238 ProbableTypo =
true;
15241 if (ProbableTypo) {
15243 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15251 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15263 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15265 RHSExpr = CE->
getArg(0);
15266 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15267 CXXSCE && CXXSCE->isXValue())
15268 RHSExpr = CXXSCE->getSubExpr();
15272 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15273 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15276 if (LHSDeclRef && RHSDeclRef) {
15283 auto D =
Diag(OpLoc, diag::warn_self_move)
15299 const Expr *LHSBase = LHSExpr;
15300 const Expr *RHSBase = RHSExpr;
15301 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15302 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15303 if (!LHSME || !RHSME)
15306 while (LHSME && RHSME) {
15313 LHSME = dyn_cast<MemberExpr>(LHSBase);
15314 RHSME = dyn_cast<MemberExpr>(RHSBase);
15317 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15318 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15319 if (LHSDeclRef && RHSDeclRef) {
15326 Diag(OpLoc, diag::warn_self_move)
15333 Diag(OpLoc, diag::warn_self_move)
15357 bool AreUnionMembers =
false) {
15361 assert(((Field1Parent->isStructureOrClassType() &&
15362 Field2Parent->isStructureOrClassType()) ||
15363 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15364 "Can't evaluate layout compatibility between a struct field and a "
15366 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15367 (AreUnionMembers && Field1Parent->isUnionType())) &&
15368 "AreUnionMembers should be 'true' for union fields (only).");
15382 if (Bits1 != Bits2)
15386 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15387 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15390 if (!AreUnionMembers &&
15402 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15403 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15405 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15406 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15411 return isLayoutCompatible(C, F1, F2);
15422 for (
auto *Field1 : RD1->
fields()) {
15423 auto I = UnmatchedFields.begin();
15424 auto E = UnmatchedFields.end();
15426 for ( ; I != E; ++I) {
15428 bool Result = UnmatchedFields.erase(*I);
15438 return UnmatchedFields.empty();
15464 if (
C.hasSameType(T1, T2))
15473 if (TC1 == Type::Enum)
15475 if (TC1 == Type::Record) {
15494 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15525 const ValueDecl **VD, uint64_t *MagicValue,
15526 bool isConstantEvaluated) {
15534 case Stmt::UnaryOperatorClass: {
15543 case Stmt::DeclRefExprClass: {
15549 case Stmt::IntegerLiteralClass: {
15551 llvm::APInt MagicValueAPInt = IL->
getValue();
15552 if (MagicValueAPInt.getActiveBits() <= 64) {
15553 *MagicValue = MagicValueAPInt.getZExtValue();
15559 case Stmt::BinaryConditionalOperatorClass:
15560 case Stmt::ConditionalOperatorClass: {
15565 isConstantEvaluated)) {
15575 case Stmt::BinaryOperatorClass: {
15578 TypeExpr = BO->
getRHS();
15608 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15611 bool isConstantEvaluated) {
15612 FoundWrongKind =
false;
15617 uint64_t MagicValue;
15619 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15623 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15624 if (I->getArgumentKind() != ArgumentKind) {
15625 FoundWrongKind =
true;
15628 TypeInfo.Type = I->getMatchingCType();
15629 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15630 TypeInfo.MustBeNull = I->getMustBeNull();
15641 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15642 if (I == MagicValues->end())
15651 bool LayoutCompatible,
15653 if (!TypeTagForDatatypeMagicValues)
15654 TypeTagForDatatypeMagicValues.reset(
15655 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15658 (*TypeTagForDatatypeMagicValues)[Magic] =
15674 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15675 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15676 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15677 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15680void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15683 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
15684 bool IsPointerAttr = Attr->getIsPointer();
15687 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
15688 if (TypeTagIdxAST >= ExprArgs.size()) {
15689 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15690 << 0 << Attr->getTypeTagIdx().getSourceIndex();
15693 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15694 bool FoundWrongKind;
15697 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15699 if (FoundWrongKind)
15701 diag::warn_type_tag_for_datatype_wrong_kind)
15707 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
15708 if (ArgumentIdxAST >= ExprArgs.size()) {
15709 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15710 << 1 << Attr->getArgumentIdx().getSourceIndex();
15713 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15714 if (IsPointerAttr) {
15716 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15717 if (ICE->getType()->isVoidPointerType() &&
15718 ICE->getCastKind() == CK_BitCast)
15719 ArgumentExpr = ICE->getSubExpr();
15721 QualType ArgumentType = ArgumentExpr->
getType();
15727 if (TypeInfo.MustBeNull) {
15732 diag::warn_type_safety_null_pointer_required)
15740 QualType RequiredType = TypeInfo.Type;
15742 RequiredType =
Context.getPointerType(RequiredType);
15744 bool mismatch =
false;
15745 if (!TypeInfo.LayoutCompatible) {
15746 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
15767 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15768 << ArgumentType << ArgumentKind
15769 << TypeInfo.LayoutCompatible << RequiredType
15787 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15795 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
15801 auto &MisalignedMembersForExpr =
15803 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15804 if (MA != MisalignedMembersForExpr.end() &&
15805 (
T->isDependentType() ||
T->isIntegerType() ||
15806 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
15808 T->getPointeeType()) <= MA->Alignment))))
15809 MisalignedMembersForExpr.erase(MA);
15818 const auto *ME = dyn_cast<MemberExpr>(E);
15830 bool AnyIsPacked =
false;
15832 QualType BaseType = ME->getBase()->getType();
15833 if (BaseType->isDependentType())
15837 auto *RD = BaseType->castAsRecordDecl();
15842 auto *FD = dyn_cast<FieldDecl>(MD);
15848 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15849 ReverseMemberChain.push_back(FD);
15852 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15854 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15861 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15872 if (ExpectedAlignment.
isOne())
15877 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15878 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
15882 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
15886 if (DRE && !TopME->
isArrow()) {
15889 CompleteObjectAlignment =
15890 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
15894 if (Offset % ExpectedAlignment != 0 ||
15897 CompleteObjectAlignment < ExpectedAlignment) {
15908 for (
FieldDecl *FDI : ReverseMemberChain) {
15909 if (FDI->hasAttr<PackedAttr>() ||
15910 FDI->getParent()->hasAttr<PackedAttr>()) {
15912 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
15918 assert(FD &&
"We did not find a packed FieldDecl!");
15919 Action(E, FD->
getParent(), FD, Alignment);
15923void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
15924 using namespace std::placeholders;
15927 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
15963bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
15964 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15977 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
15978 TheCall->
setType(VecTy0->getElementType());
15991 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16008 assert(!Args.empty() &&
"Should have at least one argument.");
16010 Expr *Arg0 = Args.front();
16013 auto EmitError = [&](
Expr *ArgI) {
16015 diag::err_typecheck_call_different_arg_types)
16016 << Arg0->
getType() << ArgI->getType();
16021 for (
Expr *ArgI : Args.drop_front())
16032 for (
Expr *ArgI : Args.drop_front()) {
16033 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16036 VecI->getElementType()) ||
16037 Vec0->getNumElements() != VecI->getNumElements()) {
16046std::optional<QualType>
16050 return std::nullopt;
16054 return std::nullopt;
16057 for (
int I = 0; I < 2; ++I) {
16061 return std::nullopt;
16062 Args[I] = Converted.
get();
16069 return std::nullopt;
16072 return std::nullopt;
16074 TheCall->
setArg(0, Args[0]);
16075 TheCall->
setArg(1, Args[1]);
16086 TheCall->
getArg(1), Loc) ||
16088 TheCall->
getArg(2), Loc))
16092 for (
int I = 0; I < 3; ++I) {
16097 Args[I] = Converted.
get();
16100 int ArgOrdinal = 1;
16101 for (
Expr *Arg : Args) {
16103 ArgTyRestr, ArgOrdinal++))
16110 for (
int I = 0; I < 3; ++I)
16111 TheCall->
setArg(I, Args[I]);
16117bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16129bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16138 diag::err_builtin_invalid_arg_type)
16139 << 1 << 2 << 1 << 1 << TyArg;
16153 Expr *Matrix = MatrixArg.
get();
16155 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16158 << 1 << 3 << 0 << 0
16165 QualType ResultType =
Context.getConstantMatrixType(
16166 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16169 TheCall->
setType(ResultType);
16172 TheCall->
setArg(0, Matrix);
16177static std::optional<unsigned>
16185 uint64_t
Dim =
Value->getZExtValue();
16204 unsigned PtrArgIdx = 0;
16205 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16206 Expr *RowsExpr = TheCall->
getArg(1);
16207 Expr *ColumnsExpr = TheCall->
getArg(2);
16208 Expr *StrideExpr = TheCall->
getArg(3);
16210 bool ArgError =
false;
16217 PtrExpr = PtrConv.
get();
16218 TheCall->
setArg(0, PtrExpr);
16225 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16226 QualType ElementTy;
16229 << PtrArgIdx + 1 << 0 << 5 << 0
16233 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16237 << PtrArgIdx + 1 << 0 << 5
16244 auto ApplyArgumentConversions = [
this](Expr *E) {
16253 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16255 RowsExpr = RowsConv.
get();
16256 TheCall->
setArg(1, RowsExpr);
16258 RowsExpr =
nullptr;
16260 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16262 ColumnsExpr = ColumnsConv.
get();
16263 TheCall->
setArg(2, ColumnsExpr);
16265 ColumnsExpr =
nullptr;
16276 std::optional<unsigned> MaybeRows;
16280 std::optional<unsigned> MaybeColumns;
16285 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16288 StrideExpr = StrideConv.
get();
16289 TheCall->
setArg(3, StrideExpr);
16292 if (std::optional<llvm::APSInt>
Value =
16295 if (Stride < *MaybeRows) {
16297 diag::err_builtin_matrix_stride_too_small);
16303 if (ArgError || !MaybeRows || !MaybeColumns)
16307 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16316 unsigned PtrArgIdx = 1;
16317 Expr *MatrixExpr = TheCall->
getArg(0);
16318 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16319 Expr *StrideExpr = TheCall->
getArg(2);
16321 bool ArgError =
false;
16327 MatrixExpr = MatrixConv.
get();
16328 TheCall->
setArg(0, MatrixExpr);
16335 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16338 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16346 PtrExpr = PtrConv.
get();
16347 TheCall->
setArg(1, PtrExpr);
16355 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16358 << PtrArgIdx + 1 << 0 << 5 << 0
16362 QualType ElementTy = PtrTy->getPointeeType();
16364 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16369 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16371 diag::err_builtin_matrix_pointer_arg_mismatch)
16372 << ElementTy << MatrixTy->getElementType();
16387 StrideExpr = StrideConv.
get();
16388 TheCall->
setArg(2, StrideExpr);
16393 if (std::optional<llvm::APSInt>
Value =
16396 if (Stride < MatrixTy->getNumRows()) {
16398 diag::err_builtin_matrix_stride_too_small);
16418 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16423 llvm::StringSet<> CalleeTCBs;
16424 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16425 CalleeTCBs.insert(A->getTCBName());
16426 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16427 CalleeTCBs.insert(A->getTCBName());
16431 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16432 StringRef CallerTCB = A->getTCBName();
16433 if (CalleeTCBs.count(CallerTCB) == 0) {
16434 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16435 << 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.