83#include "llvm/ADT/APFloat.h"
84#include "llvm/ADT/APInt.h"
85#include "llvm/ADT/APSInt.h"
86#include "llvm/ADT/ArrayRef.h"
87#include "llvm/ADT/DenseMap.h"
88#include "llvm/ADT/FoldingSet.h"
89#include "llvm/ADT/STLExtras.h"
90#include "llvm/ADT/STLForwardCompat.h"
91#include "llvm/ADT/SmallBitVector.h"
92#include "llvm/ADT/SmallPtrSet.h"
93#include "llvm/ADT/SmallString.h"
94#include "llvm/ADT/SmallVector.h"
95#include "llvm/ADT/StringExtras.h"
96#include "llvm/ADT/StringRef.h"
97#include "llvm/ADT/StringSet.h"
98#include "llvm/ADT/StringSwitch.h"
99#include "llvm/Support/AtomicOrdering.h"
100#include "llvm/Support/Compiler.h"
101#include "llvm/Support/ConvertUTF.h"
102#include "llvm/Support/ErrorHandling.h"
103#include "llvm/Support/Format.h"
104#include "llvm/Support/Locale.h"
105#include "llvm/Support/MathExtras.h"
106#include "llvm/Support/SaveAndRestore.h"
107#include "llvm/Support/raw_ostream.h"
108#include "llvm/TargetParser/RISCVTargetParser.h"
109#include "llvm/TargetParser/Triple.h"
122using namespace clang;
126 unsigned ByteNo)
const {
137 unsigned ArgCount =
Call->getNumArgs();
138 if (ArgCount >= MinArgCount)
141 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
142 << 0 << MinArgCount << ArgCount
143 << 0 <<
Call->getSourceRange();
147 unsigned ArgCount =
Call->getNumArgs();
148 if (ArgCount <= MaxArgCount)
150 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
151 << 0 << MaxArgCount << ArgCount
152 << 0 <<
Call->getSourceRange();
156 unsigned MaxArgCount) {
162 unsigned ArgCount =
Call->getNumArgs();
163 if (ArgCount == DesiredArgCount)
168 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
172 Call->getArg(ArgCount - 1)->getEndLoc());
174 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
175 << 0 << DesiredArgCount << ArgCount
180 bool HasError =
false;
182 for (
const Expr *Arg :
Call->arguments()) {
183 if (Arg->isValueDependent())
186 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
187 int DiagMsgKind = -1;
189 if (!ArgString.has_value())
191 else if (ArgString->find(
'$') != std::string::npos)
194 if (DiagMsgKind >= 0) {
195 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
196 << DiagMsgKind << Arg->getSourceRange();
205 if (
Value->isTypeDependent())
236 if (!Literal || !Literal->isOrdinary()) {
249 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
257 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
258 if (!Literal || !Literal->isWide()) {
259 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
260 << Arg->getSourceRange();
306 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
337 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
339 auto IsValidIntegerType = [](
QualType Ty) {
340 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
347 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
349 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
352 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
354 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
356 S.
Diag(Source->getExprLoc(),
357 diag::note_alignment_invalid_function_pointer);
362 if (!IsValidIntegerType(AlignOp->
getType())) {
373 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
374 llvm::APSInt MaxValue(
375 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
376 if (AlignValue < 1) {
377 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
380 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
385 if (!AlignValue.isPowerOf2()) {
386 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
389 if (AlignValue == 1) {
390 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
391 << IsBooleanAlignBuiltin;
419 std::pair<unsigned, const char *> Builtins[] = {
420 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
421 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
422 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
425 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
432 auto ValidCkdIntType = [](
QualType QT) {
435 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
436 return (BT->getKind() >= BuiltinType::Short &&
437 BT->getKind() <= BuiltinType::Int128) || (
438 BT->getKind() >= BuiltinType::UShort &&
439 BT->getKind() <= BuiltinType::UInt128) ||
440 BT->getKind() == BuiltinType::UChar ||
441 BT->getKind() == BuiltinType::SChar;
446 for (
unsigned I = 0; I < 2; ++I) {
452 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
471 !PtrTy->getPointeeType()->isIntegerType() ||
472 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
473 PtrTy->getPointeeType().isConstQualified()) {
475 diag::err_overflow_builtin_must_be_ptr_int)
483 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
484 for (
unsigned I = 0; I < 3; ++I) {
485 const auto Arg = TheCall->
getArg(I);
488 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
490 return S.
Diag(Arg->getBeginLoc(),
491 diag::err_overflow_builtin_bit_int_max_size)
500struct BuiltinDumpStructGenerator {
504 SmallVector<Expr *, 32> Actions;
505 DiagnosticErrorTrap ErrorTracker;
506 PrintingPolicy Policy;
508 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
509 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
510 Policy(S.Context.getPrintingPolicy()) {
512 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
515 Expr *makeOpaqueValueExpr(Expr *Inner) {
519 Actions.push_back(OVE);
523 Expr *getStringLiteral(llvm::StringRef Str) {
526 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
529 bool callPrintFunction(llvm::StringRef Format,
530 llvm::ArrayRef<Expr *> Exprs = {}) {
531 SmallVector<Expr *, 8> Args;
533 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
535 Args.push_back(getStringLiteral(Format));
536 llvm::append_range(Args, Exprs);
539 Sema::CodeSynthesisContext Ctx;
552 Actions.push_back(RealCall.
get());
558 Expr *getIndentString(
unsigned Depth) {
562 llvm::SmallString<32>
Indent;
564 return getStringLiteral(
Indent);
568 return getStringLiteral(
T.getAsString(Policy));
571 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
572 llvm::raw_svector_ostream
OS(Str);
576 if (
auto *BT =
T->
getAs<BuiltinType>()) {
577 switch (BT->getKind()) {
578 case BuiltinType::Bool:
581 case BuiltinType::Char_U:
582 case BuiltinType::UChar:
585 case BuiltinType::Char_S:
586 case BuiltinType::SChar:
594 analyze_printf::PrintfSpecifier
Specifier;
597 if (
Specifier.getConversionSpecifier().getKind() ==
598 analyze_printf::PrintfConversionSpecifier::sArg) {
604 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
624 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
625 Expr *IndentLit = getIndentString(Depth);
627 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
628 : callPrintFunction(
"%s", {TypeLit}))
631 return dumpRecordValue(RD, E, IndentLit, Depth);
635 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
644 Expr *RecordArg = makeOpaqueValueExpr(E);
647 if (callPrintFunction(
" {\n"))
651 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
652 for (
const auto &Base : CXXRD->bases()) {
660 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
666 Expr *FieldIndentArg = getIndentString(Depth + 1);
669 for (
auto *D : RD->
decls()) {
670 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
671 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
672 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
675 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
676 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
678 getStringLiteral(FD->getName())};
680 if (FD->isBitField()) {
684 FD->getBitWidthValue());
692 CXXScopeSpec(), Loc, IFD,
695 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
697 DeclarationNameInfo(FD->getDeclName(), Loc));
698 if (
Field.isInvalid())
701 auto *InnerRD = FD->getType()->getAsRecordDecl();
702 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
703 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
705 if (callPrintFunction(Format, Args) ||
706 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
710 if (appendFormatSpecifier(FD->getType(), Format)) {
712 Args.push_back(
Field.get());
722 Args.push_back(FieldAddr.
get());
725 if (callPrintFunction(Format, Args))
730 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
731 : callPrintFunction(
"}\n");
734 Expr *buildWrapper() {
737 TheCall->
setType(Wrapper->getType());
758 diag::err_expected_struct_pointer_argument)
767 diag::err_incomplete_type))
776 switch (BT ? BT->getKind() : BuiltinType::Void) {
777 case BuiltinType::Dependent:
778 case BuiltinType::Overload:
779 case BuiltinType::BoundMember:
780 case BuiltinType::PseudoObject:
781 case BuiltinType::UnknownAny:
782 case BuiltinType::BuiltinFn:
788 diag::err_expected_callable_argument)
794 BuiltinDumpStructGenerator Generator(S, TheCall);
800 Expr *PtrArg = PtrArgResult.
get();
804 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
807 return Generator.buildWrapper();
819 if (
Call->getStmtClass() != Stmt::CallExprClass) {
820 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
821 <<
Call->getSourceRange();
826 if (CE->getCallee()->getType()->isBlockPointerType()) {
827 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
828 <<
Call->getSourceRange();
832 const Decl *TargetDecl = CE->getCalleeDecl();
833 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
834 if (FD->getBuiltinID()) {
835 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
836 <<
Call->getSourceRange();
841 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
842 <<
Call->getSourceRange();
850 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
864 BuiltinCall->
setType(CE->getType());
868 BuiltinCall->
setArg(1, ChainResult.
get());
875class ScanfDiagnosticFormatHandler
879 using ComputeSizeFunction =
880 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
884 using DiagnoseFunction =
885 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
887 ComputeSizeFunction ComputeSizeArgument;
888 DiagnoseFunction Diagnose;
891 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
892 DiagnoseFunction Diagnose)
893 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
895 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
896 const char *StartSpecifier,
897 unsigned specifierLen)
override {
901 unsigned NulByte = 0;
913 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
915 analyze_format_string::OptionalAmount::HowSpecified::Constant)
920 std::optional<llvm::APSInt> DestSizeAPS =
925 unsigned DestSize = DestSizeAPS->getZExtValue();
927 if (DestSize < SourceSize)
934class EstimateSizeFormatHandler
939 bool IsKernelCompatible =
true;
942 EstimateSizeFormatHandler(StringRef Format)
943 :
Size(std::
min(Format.find(0), Format.size()) +
946 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
947 const char *,
unsigned SpecifierLen,
948 const TargetInfo &)
override {
950 const size_t FieldWidth = computeFieldWidth(FS);
951 const size_t Precision = computePrecision(FS);
958 Size += std::max(FieldWidth, (
size_t)1);
970 Size += std::max(FieldWidth, Precision);
986 Size += std::max(FieldWidth, 1 +
987 (Precision ? 1 + Precision
997 (Precision ? 1 + Precision : 0) +
1005 std::max(FieldWidth,
1007 (Precision ? 1 + Precision : 0) +
1022 IsKernelCompatible =
false;
1023 Size += std::max(FieldWidth, 2 + Precision);
1070 Size += (Precision ? 0 : 1);
1077 assert(SpecifierLen <= Size &&
"no underflow");
1078 Size -= SpecifierLen;
1082 size_t getSizeLowerBound()
const {
return Size; }
1083 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1086 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1087 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1088 size_t FieldWidth = 0;
1094 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1095 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1096 size_t Precision = 0;
1143 StringRef &FormatStrRef,
size_t &StrLen,
1145 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1146 Format && (Format->isOrdinary() || Format->isUTF8())) {
1147 FormatStrRef = Format->getString();
1149 Context.getAsConstantArrayType(Format->getType());
1150 assert(
T &&
"String literal not of constant array type!");
1151 size_t TypeSize =
T->getZExtSize();
1153 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1161class FortifiedBufferChecker {
1163 FortifiedBufferChecker(Sema &S, FunctionDecl *FD, CallExpr *TheCall)
1164 : S(S), TheCall(TheCall), FD(FD),
1165 DABAttr(FD ? FD->getAttr<DiagnoseAsBuiltinAttr>() :
nullptr) {
1170 std::optional<unsigned> TranslateIndex(
unsigned Index) {
1175 unsigned NewIndex = Index;
1177 unsigned DABIndices = DABAttr->argIndices_size();
1178 NewIndex = Index < DABIndices ? DABAttr->argIndices_begin()[Index]
1182 return std::nullopt;
1188 std::optional<llvm::APSInt> EvaluateIntegerArgument(
unsigned Index) {
1189 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1191 return std::nullopt;
1193 Expr *Arg = TheCall->
getArg(*IndexOptional);
1195 return std::nullopt;
1197 return Result.Val.getInt();
1200 std::optional<llvm::APSInt>
1201 ComputeExplicitObjectSizeArgument(
unsigned Index) {
1202 std::optional<llvm::APSInt>
Integer = EvaluateIntegerArgument(Index);
1204 return std::nullopt;
1210 std::optional<llvm::APSInt> ComputeSizeArgument(
unsigned Index) {
1216 if (Index < FD->getNumParams()) {
1217 if (
const auto *POS =
1219 BOSType = POS->getType();
1222 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1224 return std::nullopt;
1226 const Expr *ObjArg = TheCall->
getArg(*IndexOptional);
1227 if (std::optional<uint64_t> ObjSize =
1230 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1232 return std::nullopt;
1235 std::optional<llvm::APSInt>
1236 ComputeExplicitObjectSizeArgumentProduct(
unsigned LIndex,
unsigned RIndex) {
1237 auto L = ComputeExplicitObjectSizeArgument(LIndex);
1238 auto R = ComputeExplicitObjectSizeArgument(RIndex);
1240 return std::nullopt;
1243 2 * std::max({L->getBitWidth(),
R->getBitWidth(), SizeTypeWidth});
1245 llvm::APSInt
LE = L->extOrTrunc(W);
1246 llvm::APSInt RE =
R->extOrTrunc(W);
1251 std::optional<llvm::APSInt> ComputeStrLenArgument(
unsigned Index) {
1252 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1254 return std::nullopt;
1255 unsigned NewIndex = *IndexOptional;
1257 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1259 if (std::optional<uint64_t>
Result =
1262 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1264 return std::nullopt;
1267 unsigned getSizeTypeWidth()
const {
return SizeTypeWidth; }
1269 unsigned getBuiltinID()
const {
1270 const FunctionDecl *UseDecl = FD;
1272 UseDecl = DABAttr->getFunction();
1273 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1280 unsigned ID = getBuiltinID();
1284 assert(Callee &&
"expected callee");
1285 return Callee->getName().str();
1288 StringRef Ref = Name;
1290 if (!(Ref.consume_front(
"__builtin___") && Ref.consume_back(
"_chk")))
1291 Ref.consume_front(
"__builtin_");
1292 assert(!Ref.empty() &&
"expected non-empty function name");
1297 void checkSourceOverread(
unsigned SrcArgIdx,
unsigned SizeArgIdx) {
1301 const Expr *SrcArg = TheCall->
getArg(SrcArgIdx);
1302 const Expr *SizeArg = TheCall->
getArg(SizeArgIdx);
1307 std::optional<llvm::APSInt> CopyLen =
1308 ComputeExplicitObjectSizeArgument(SizeArgIdx);
1309 std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx);
1311 if (!CopyLen || !SrcBufSize)
1315 if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0)
1319 S.
PDiag(diag::warn_stringop_overread)
1321 << SrcBufSize->getZExtValue());
1328 const DiagnoseAsBuiltinAttr *DABAttr;
1329 unsigned SizeTypeWidth;
1333void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1338 FortifiedBufferChecker Checker(*
this, FD, TheCall);
1340 unsigned BuiltinID = Checker.getBuiltinID();
1344 unsigned SizeTypeWidth = Checker.getSizeTypeWidth();
1346 std::optional<llvm::APSInt> AccessSize;
1347 std::optional<llvm::APSInt> BufferSize;
1348 unsigned DiagID = 0;
1350 switch (BuiltinID) {
1353 case Builtin::BI__builtin_strcat:
1354 case Builtin::BIstrcat:
1355 case Builtin::BI__builtin_stpcpy:
1356 case Builtin::BIstpcpy:
1357 case Builtin::BI__builtin_strcpy:
1358 case Builtin::BIstrcpy: {
1359 DiagID = diag::warn_fortify_strlen_overflow;
1360 AccessSize = Checker.ComputeStrLenArgument(1);
1361 BufferSize = Checker.ComputeSizeArgument(0);
1365 case Builtin::BI__builtin___strcat_chk:
1366 case Builtin::BI__builtin___stpcpy_chk:
1367 case Builtin::BI__builtin___strcpy_chk: {
1368 DiagID = diag::warn_fortify_strlen_overflow;
1369 AccessSize = Checker.ComputeStrLenArgument(1);
1370 BufferSize = Checker.ComputeExplicitObjectSizeArgument(2);
1374 case Builtin::BIscanf:
1375 case Builtin::BIfscanf:
1376 case Builtin::BIsscanf: {
1377 unsigned FormatIndex = 1;
1378 unsigned DataIndex = 2;
1379 if (BuiltinID == Builtin::BIscanf) {
1384 const auto *FormatExpr =
1387 StringRef FormatStrRef;
1392 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1393 unsigned SourceSize) {
1394 DiagID = diag::warn_fortify_scanf_overflow;
1395 unsigned Index = ArgIndex + DataIndex;
1396 std::string FunctionName = Checker.getFunctionName();
1398 PDiag(DiagID) << FunctionName << (Index + 1)
1399 << DestSize << SourceSize);
1402 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1403 return Checker.ComputeSizeArgument(Index + DataIndex);
1405 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1406 const char *FormatBytes = FormatStrRef.data();
1417 case Builtin::BIsprintf:
1418 case Builtin::BI__builtin_sprintf:
1419 case Builtin::BI__builtin___sprintf_chk:
1420 case Builtin::BIvsprintf:
1421 case Builtin::BI__builtin_vsprintf:
1422 case Builtin::BI__builtin___vsprintf_chk: {
1423 bool IsChk = BuiltinID == Builtin::BI__builtin___sprintf_chk ||
1424 BuiltinID == Builtin::BI__builtin___vsprintf_chk;
1425 std::optional<unsigned> FormatIndex = Checker.TranslateIndex(IsChk ? 3 : 1);
1428 const auto *FormatExpr =
1431 StringRef FormatStrRef;
1434 EstimateSizeFormatHandler H(FormatStrRef);
1435 const char *FormatBytes = FormatStrRef.data();
1437 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1438 Context.getTargetInfo(),
false)) {
1439 DiagID = H.isKernelCompatible()
1440 ? diag::warn_format_overflow
1441 : diag::warn_format_overflow_non_kprintf;
1442 AccessSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1443 .extOrTrunc(SizeTypeWidth);
1445 BufferSize = Checker.ComputeExplicitObjectSizeArgument(2);
1447 BufferSize = Checker.ComputeSizeArgument(0);
1454 case Builtin::BI__builtin___memcpy_chk:
1455 case Builtin::BI__builtin___memmove_chk:
1456 case Builtin::BI__builtin___memset_chk:
1457 case Builtin::BI__builtin___strlcat_chk:
1458 case Builtin::BI__builtin___strlcpy_chk:
1459 case Builtin::BI__builtin___strncat_chk:
1460 case Builtin::BI__builtin___strncpy_chk:
1461 case Builtin::BI__builtin___stpncpy_chk:
1462 case Builtin::BI__builtin___memccpy_chk:
1463 case Builtin::BI__builtin___mempcpy_chk: {
1464 DiagID = diag::warn_builtin_chk_overflow;
1466 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1468 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1470 if (BuiltinID == Builtin::BI__builtin___memcpy_chk ||
1471 BuiltinID == Builtin::BI__builtin___memmove_chk ||
1472 BuiltinID == Builtin::BI__builtin___mempcpy_chk) {
1473 Checker.checkSourceOverread(1, 2);
1478 case Builtin::BI__builtin___snprintf_chk:
1479 case Builtin::BI__builtin___vsnprintf_chk: {
1480 DiagID = diag::warn_builtin_chk_overflow;
1481 AccessSize = Checker.ComputeExplicitObjectSizeArgument(1);
1482 BufferSize = Checker.ComputeExplicitObjectSizeArgument(3);
1486 case Builtin::BIstrncat:
1487 case Builtin::BI__builtin_strncat:
1488 case Builtin::BIstrncpy:
1489 case Builtin::BI__builtin_strncpy:
1490 case Builtin::BIstpncpy:
1491 case Builtin::BI__builtin_stpncpy:
1492 case Builtin::BIstrlcat:
1493 case Builtin::BI__builtin_strlcat:
1494 case Builtin::BIstrlcpy:
1495 case Builtin::BI__builtin_strlcpy: {
1501 DiagID = diag::warn_fortify_source_size_mismatch;
1503 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1504 BufferSize = Checker.ComputeSizeArgument(0);
1508 case Builtin::BIrecv:
1509 case Builtin::BIrecvfrom: {
1510 unsigned ExpectedArgs = BuiltinID == Builtin::BIrecv ? 4 : 6;
1515 DiagID = diag::warn_fortify_source_size_mismatch;
1516 AccessSize = Checker.ComputeExplicitObjectSizeArgument(2);
1517 BufferSize = Checker.ComputeSizeArgument(1);
1521 case Builtin::BIpoll:
1522 case Builtin::BIppoll:
1523 case Builtin::BIppoll64: {
1524 unsigned ExpectedArgs = BuiltinID == Builtin::BIpoll ? 3 : 4;
1534 if (BuiltinID == Builtin::BIpoll) {
1539 if (TmoPointeeTy.
isNull())
1546 std::optional<CharUnits> ElemSize =
1547 Context.getTypeSizeInCharsIfKnown(PointeeTy);
1550 std::optional<llvm::APSInt> Count =
1551 Checker.ComputeExplicitObjectSizeArgument(1);
1554 DiagID = diag::warn_fortify_source_size_mismatch;
1555 unsigned WideWidth = SizeTypeWidth * 2;
1556 AccessSize = Count->extOrTrunc(WideWidth) *
1557 llvm::APSInt(llvm::APInt(WideWidth, ElemSize->getQuantity()),
1559 BufferSize = Checker.ComputeSizeArgument(0);
1563 case Builtin::BIbzero:
1564 case Builtin::BI__builtin_bzero:
1565 case Builtin::BImemcpy:
1566 case Builtin::BI__builtin_memcpy:
1567 case Builtin::BImemmove:
1568 case Builtin::BI__builtin_memmove:
1569 case Builtin::BImemset:
1570 case Builtin::BI__builtin_memset:
1571 case Builtin::BImempcpy:
1572 case Builtin::BI__builtin_mempcpy: {
1573 DiagID = diag::warn_fortify_source_overflow;
1575 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1576 BufferSize = Checker.ComputeSizeArgument(0);
1579 if (BuiltinID != Builtin::BImemset &&
1580 BuiltinID != Builtin::BI__builtin_memset &&
1581 BuiltinID != Builtin::BIbzero &&
1582 BuiltinID != Builtin::BI__builtin_bzero) {
1583 Checker.checkSourceOverread(1, 2);
1587 case Builtin::BIbcopy:
1588 case Builtin::BI__builtin_bcopy: {
1589 DiagID = diag::warn_fortify_source_overflow;
1591 Checker.ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1592 BufferSize = Checker.ComputeSizeArgument(1);
1593 Checker.checkSourceOverread(0, 2);
1596 case Builtin::BIfread: {
1597 DiagID = diag::warn_fortify_source_overflow;
1598 AccessSize = Checker.ComputeExplicitObjectSizeArgumentProduct(1, 2);
1599 BufferSize = Checker.ComputeSizeArgument(0);
1602 case Builtin::BIfwrite: {
1603 DiagID = diag::warn_fortify_source_overread;
1604 AccessSize = Checker.ComputeExplicitObjectSizeArgumentProduct(1, 2);
1605 BufferSize = Checker.ComputeSizeArgument(0);
1608 case Builtin::BIfgets: {
1609 AccessSize = Checker.EvaluateIntegerArgument(1);
1611 if (AccessSize && AccessSize->isNegative()) {
1613 PDiag(diag::warn_fortify_source_negative_size)
1614 << Checker.getFunctionName());
1618 DiagID = diag::warn_fortify_source_size_mismatch;
1619 BufferSize = Checker.ComputeSizeArgument(0);
1623 case Builtin::BImemchr:
1624 case Builtin::BI__builtin_memchr: {
1625 Checker.checkSourceOverread(0, 2);
1631 case Builtin::BImemcmp:
1632 case Builtin::BI__builtin_memcmp:
1633 case Builtin::BIbcmp:
1634 case Builtin::BI__builtin_bcmp: {
1635 Checker.checkSourceOverread(0, 2);
1636 Checker.checkSourceOverread(1, 2);
1639 case Builtin::BIsnprintf:
1640 case Builtin::BI__builtin_snprintf:
1641 case Builtin::BIvsnprintf:
1642 case Builtin::BI__builtin_vsnprintf: {
1643 DiagID = diag::warn_fortify_source_size_mismatch;
1644 AccessSize = Checker.ComputeExplicitObjectSizeArgument(1);
1646 StringRef FormatStrRef;
1650 EstimateSizeFormatHandler H(FormatStrRef);
1651 const char *FormatBytes = FormatStrRef.data();
1653 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1654 Context.getTargetInfo(),
false)) {
1655 llvm::APSInt FormatSize =
1656 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1657 .extOrTrunc(SizeTypeWidth);
1658 if (FormatSize > *AccessSize && *AccessSize != 0) {
1659 unsigned TruncationDiagID =
1660 H.isKernelCompatible() ? diag::warn_format_truncation
1661 : diag::warn_format_truncation_non_kprintf;
1662 SmallString<16> SpecifiedSizeStr;
1663 SmallString<16> FormatSizeStr;
1664 AccessSize->toString(SpecifiedSizeStr, 10);
1665 FormatSize.toString(FormatSizeStr, 10);
1667 PDiag(TruncationDiagID)
1668 << Checker.getFunctionName()
1669 << SpecifiedSizeStr << FormatSizeStr);
1673 BufferSize = Checker.ComputeSizeArgument(0);
1677 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1681 if (!AccessSize || !BufferSize ||
1682 llvm::APSInt::compareValues(*AccessSize, *BufferSize) <= 0)
1685 std::string FunctionName = Checker.getFunctionName();
1687 SmallString<16> BufferSizeStr;
1688 SmallString<16> AccessSizeStr;
1689 BufferSize->toString(BufferSizeStr, 10);
1690 AccessSize->toString(AccessSizeStr, 10);
1693 << FunctionName << BufferSizeStr << AccessSizeStr);
1713 Expr *Arg = TheCall->
getArg(0);
1721 llvm::APInt RawValue =
R.Val.getInt();
1722 llvm::APInt Mask(RawValue.getBitWidth(), 0777);
1723 llvm::APInt
Extra = RawValue & ~Mask;
1726 SmallString<16> ExtraStr;
1727 Extra.toString(ExtraStr, 8,
false);
1744 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1747 << DRE->getDecl()->getIdentifier();
1759 "__builtin_alloca has invalid address space");
1785enum PointerAuthOpKind {
1801 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1832 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1835 llvm::raw_svector_ostream Str(
Value);
1844 Result = KeyValue->getZExtValue();
1863 bool IsAddrDiscArg =
false;
1868 IsAddrDiscArg =
true;
1877 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1878 <<
Result->getExtValue();
1880 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1886 IntVal =
Result->getZExtValue();
1890static std::pair<const ValueDecl *, CharUnits>
1897 const auto *BaseDecl =
1902 return {BaseDecl,
Result.Val.getLValueOffset()};
1906 bool RequireConstant =
false) {
1914 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1915 return OpKind != PAO_BlendInteger;
1917 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1918 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1919 OpKind == PAO_SignGeneric || OpKind == PAO_BlendPC;
1928 }
else if (AllowsInteger(OpKind) &&
1935 <<
unsigned(OpKind == PAO_Discriminator ? 1
1936 : OpKind == PAO_BlendPointer ? 2
1937 : OpKind == PAO_BlendInteger ? 3
1938 : OpKind == PAO_BlendPC ? 4
1940 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1950 if (!RequireConstant) {
1952 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1955 ? diag::warn_ptrauth_sign_null_pointer
1956 : diag::warn_ptrauth_auth_null_pointer)
1966 if (OpKind == PAO_Sign) {
1984 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1989 assert(OpKind == PAO_Discriminator);
1995 if (
Call->getBuiltinCallee() ==
1996 Builtin::BI__builtin_ptrauth_blend_discriminator) {
2011 assert(
Pointer->getType()->isPointerType());
2023 assert(
Integer->getType()->isIntegerType());
2029 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
2042 Call->setType(
Call->getArgs()[0]->getType());
2073 PointerAuthOpKind OpKind,
2074 bool RequireConstant) {
2085 Call->setType(
Call->getArgs()[0]->getType());
2101 Call->setType(
Call->getArgs()[0]->getType());
2122 unsigned OldKey = 0;
2125 if (OldKey !=
static_cast<unsigned>(AK::ASIA) &&
2126 OldKey !=
static_cast<unsigned>(AK::ASIB)) {
2127 S.
Diag(
Call->getArgs()[1]->getExprLoc(),
2128 diag::err_ptrauth_auth_with_pc_and_resign_invalid_key)
2129 << OldKey <<
Call->getArgs()[1]->getSourceRange();
2134 Call->setType(
Call->getArgs()[0]->getType());
2143 const Expr *AddendExpr =
Call->getArg(5);
2145 if (!AddendIsConstInt) {
2146 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
2160 Call->setType(
Call->getArgs()[0]->getType());
2169 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
2172 const auto *Literal = dyn_cast<StringLiteral>(Arg);
2173 if (!Literal || Literal->getCharByteWidth() != 1) {
2189 Call->setArg(0, FirstValue.
get());
2195 if (!FirstArgRecord) {
2196 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2197 << 0 << FirstArgType;
2202 diag::err_get_vtable_pointer_requires_complete_type)) {
2207 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
2208 << 1 << FirstArgRecord;
2212 Call->setType(ReturnType);
2237 auto DiagSelect = [&]() -> std::optional<unsigned> {
2244 return std::optional<unsigned>{};
2259 diag::err_incomplete_type))
2263 "Unhandled non-object pointer case");
2291 if (PT->getPointeeType()->isFunctionType()) {
2293 diag::err_builtin_is_within_lifetime_invalid_arg)
2299 if (PT->getPointeeType()->isVariableArrayType()) {
2301 << 1 <<
"__builtin_is_within_lifetime";
2306 diag::err_builtin_is_within_lifetime_invalid_arg)
2320 diag::err_builtin_trivially_relocate_invalid_arg_type)
2327 diag::err_incomplete_type))
2331 T->isIncompleteArrayType()) {
2333 diag::err_builtin_trivially_relocate_invalid_arg_type)
2334 << (
T.isConstQualified() ? 1 : 2);
2343 diag::err_builtin_trivially_relocate_invalid_arg_type)
2350 if (Size.isInvalid())
2354 if (Size.isInvalid())
2356 SizeExpr = Size.get();
2357 TheCall->
setArg(2, SizeExpr);
2367 llvm::Triple::ObjectFormatType CurObjFormat =
2369 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2382 llvm::Triple::ArchType CurArch =
2384 if (llvm::is_contained(SupportedArchs, CurArch))
2394bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2401 case llvm::Triple::arm:
2402 case llvm::Triple::armeb:
2403 case llvm::Triple::thumb:
2404 case llvm::Triple::thumbeb:
2406 case llvm::Triple::aarch64:
2407 case llvm::Triple::aarch64_32:
2408 case llvm::Triple::aarch64_be:
2410 case llvm::Triple::bpfeb:
2411 case llvm::Triple::bpfel:
2413 case llvm::Triple::dxil:
2415 case llvm::Triple::hexagon:
2417 case llvm::Triple::mips:
2418 case llvm::Triple::mipsel:
2419 case llvm::Triple::mips64:
2420 case llvm::Triple::mips64el:
2422 case llvm::Triple::spirv:
2423 case llvm::Triple::spirv32:
2424 case llvm::Triple::spirv64:
2425 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2428 case llvm::Triple::systemz:
2430 case llvm::Triple::x86:
2431 case llvm::Triple::x86_64:
2433 case llvm::Triple::ppc:
2434 case llvm::Triple::ppcle:
2435 case llvm::Triple::ppc64:
2436 case llvm::Triple::ppc64le:
2438 case llvm::Triple::amdgpu:
2440 case llvm::Triple::riscv32:
2441 case llvm::Triple::riscv64:
2442 case llvm::Triple::riscv32be:
2443 case llvm::Triple::riscv64be:
2445 case llvm::Triple::loongarch32:
2446 case llvm::Triple::loongarch64:
2449 case llvm::Triple::wasm32:
2450 case llvm::Triple::wasm64:
2452 case llvm::Triple::nvptx:
2453 case llvm::Triple::nvptx64:
2459 return T->isDependentType() ||
2460 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2475 switch (ArgTyRestr) {
2479 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2480 << ArgOrdinal << 2 << 1 << 1
2487 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2488 << ArgOrdinal << 5 << 0
2494 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2495 << ArgOrdinal << 5 << 1
2501 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2515 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2516 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2517 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2518 "Expecting __builtin_cpu_...");
2520 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2522 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2523 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2524 (!IsCPUSupports && TInfo->supportsCpuIs()));
2526 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2533 ? diag::err_builtin_aix_os_unsupported
2534 : diag::err_builtin_target_unsupported)
2540 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2578 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2579 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2580 BT->getNumBits() != 1) {
2582 << ArgTy << BT->getNumBits();
2658 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2661 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2670 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2671 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2691 TheCall->
setArg(0, Arg0);
2708 TheCall->
setArg(1, Arg1);
2714 << 2 << 1 << 4 << 0 << Arg1Ty;
2728 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2730 << (OnlyUnsigned ? 3 : 1)
2738 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2741 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2746 return emitError(S, Loc,
T);
2751 return emitError(S, Loc,
T);
2757 return emitError(S, Loc,
T);
2762 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2767 return emitError(S, Loc,
T);
2772 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2778 llvm_unreachable(
"conversion functions are permitted");
2797 TheCall->
setArg(0, Arg0);
2811 TheCall->
setArg(1, Arg1);
2822 unsigned Pos,
bool AllowConst,
2826 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2831 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2832 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2833 << Pos <<
"scalar pointer";
2842 diag::err_typecheck_convert_incompatible)
2851 bool TypeDependent =
false;
2852 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2880 Builtin::BI__builtin_masked_load))
2894 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2917 Builtin::BI__builtin_masked_store))
2925 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2936 << MaskTy << ValTy);
2940 PtrTy->getPointeeType().getUnqualifiedType()))
2942 diag::err_vec_builtin_incompatible_vector)
2971 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2984 << MaskTy << IdxTy);
2993 diag::err_vec_masked_load_store_ptr)
3022 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
3037 << MaskTy << IdxTy);
3043 << MaskTy << ValTy);
3046 PtrTy->getPointeeType().getUnqualifiedType()))
3048 diag::err_vec_builtin_incompatible_vector)
3062 if (Args.size() == 0) {
3064 diag::err_typecheck_call_too_few_args_at_least)
3070 QualType FuncT = Args[0]->getType();
3073 if (Args.size() < 2) {
3075 diag::err_typecheck_call_too_few_args_at_least)
3081 const Type *MemPtrClass = MPT->getQualifier().getAsType();
3082 QualType ObjectT = Args[1]->getType();
3084 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
3133 tok::periodstar, ObjectArg.
get(), Args[0]);
3137 if (MPT->isMemberDataPointer())
3141 auto *MemCall =
new (S.
Context)
3165 return TyA->getElementType();
3172Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
3177 unsigned ICEArguments = 0;
3179 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
3184 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
3186 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
3191 if (ArgNo < TheCall->getNumArgs() &&
3194 ICEArguments &= ~(1 << ArgNo);
3198 switch (BuiltinID) {
3199 case Builtin::BI__builtin___get_unsafe_stack_start:
3200 case Builtin::BI__builtin___get_unsafe_stack_bottom:
3202 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3203 <<
"__safestack_get_unsafe_stack_bottom";
3205 case Builtin::BI__builtin___get_unsafe_stack_top:
3207 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3208 <<
"__safestack_get_unsafe_stack_top";
3210 case Builtin::BI__builtin___get_unsafe_stack_ptr:
3212 <<
Context.BuiltinInfo.getQuotedName(BuiltinID)
3213 <<
"__safestack_get_unsafe_stack_ptr";
3215 case Builtin::BI__builtin_cpu_supports:
3216 case Builtin::BI__builtin_cpu_is:
3218 Context.getAuxTargetInfo(), BuiltinID))
3221 case Builtin::BI__builtin_cpu_init:
3222 if (!
Context.getTargetInfo().supportsCpuInit()) {
3228 case Builtin::BI__builtin___CFStringMakeConstantString:
3232 *
this, BuiltinID, TheCall,
3233 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
3236 "Wrong # arguments to builtin CFStringMakeConstantString");
3237 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
3240 case Builtin::BI__builtin_ms_va_start:
3241 case Builtin::BI__builtin_zos_va_start:
3242 case Builtin::BI__builtin_stdarg_start:
3243 case Builtin::BI__builtin_va_start:
3244 case Builtin::BI__builtin_c23_va_start:
3245 if (BuiltinVAStart(BuiltinID, TheCall))
3248 case Builtin::BI__va_start: {
3249 switch (
Context.getTargetInfo().getTriple().getArch()) {
3250 case llvm::Triple::aarch64:
3251 case llvm::Triple::arm:
3252 case llvm::Triple::thumb:
3253 if (BuiltinVAStartARMMicrosoft(TheCall))
3257 if (BuiltinVAStart(BuiltinID, TheCall))
3265 case Builtin::BI_interlockedbittestandset_acq:
3266 case Builtin::BI_interlockedbittestandset_rel:
3267 case Builtin::BI_interlockedbittestandset_nf:
3268 case Builtin::BI_interlockedbittestandreset_acq:
3269 case Builtin::BI_interlockedbittestandreset_rel:
3270 case Builtin::BI_interlockedbittestandreset_nf:
3273 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
3278 case Builtin::BI_bittest64:
3279 case Builtin::BI_bittestandcomplement64:
3280 case Builtin::BI_bittestandreset64:
3281 case Builtin::BI_bittestandset64:
3282 case Builtin::BI_interlockedbittestandreset64:
3283 case Builtin::BI_interlockedbittestandset64:
3286 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
3287 llvm::Triple::aarch64, llvm::Triple::amdgpu}))
3292 case Builtin::BI_interlockedbittestandreset64_acq:
3293 case Builtin::BI_interlockedbittestandreset64_rel:
3294 case Builtin::BI_interlockedbittestandreset64_nf:
3295 case Builtin::BI_interlockedbittestandset64_acq:
3296 case Builtin::BI_interlockedbittestandset64_rel:
3297 case Builtin::BI_interlockedbittestandset64_nf:
3302 case Builtin::BI__builtin_set_flt_rounds:
3305 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3306 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgpu,
3307 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3308 llvm::Triple::ppc64le}))
3312 case Builtin::BI__builtin_isgreater:
3313 case Builtin::BI__builtin_isgreaterequal:
3314 case Builtin::BI__builtin_isless:
3315 case Builtin::BI__builtin_islessequal:
3316 case Builtin::BI__builtin_islessgreater:
3317 case Builtin::BI__builtin_isunordered:
3318 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3321 case Builtin::BI__builtin_fpclassify:
3322 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3325 case Builtin::BI__builtin_isfpclass:
3326 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3329 case Builtin::BI__builtin_isfinite:
3330 case Builtin::BI__builtin_isinf:
3331 case Builtin::BI__builtin_isinf_sign:
3332 case Builtin::BI__builtin_isnan:
3333 case Builtin::BI__builtin_issignaling:
3334 case Builtin::BI__builtin_isnormal:
3335 case Builtin::BI__builtin_issubnormal:
3336 case Builtin::BI__builtin_iszero:
3337 case Builtin::BI__builtin_signbit:
3338 case Builtin::BI__builtin_signbitf:
3339 case Builtin::BI__builtin_signbitl:
3340 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3343 case Builtin::BI__builtin_shufflevector:
3347 case Builtin::BI__builtin_masked_load:
3348 case Builtin::BI__builtin_masked_expand_load:
3350 case Builtin::BI__builtin_masked_store:
3351 case Builtin::BI__builtin_masked_compress_store:
3353 case Builtin::BI__builtin_masked_gather:
3355 case Builtin::BI__builtin_masked_scatter:
3357 case Builtin::BI__builtin_invoke:
3359 case Builtin::BI__builtin_prefetch:
3360 if (BuiltinPrefetch(TheCall))
3363 case Builtin::BI__builtin_alloca_with_align:
3364 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3365 if (BuiltinAllocaWithAlign(TheCall))
3368 case Builtin::BI__builtin_alloca:
3369 case Builtin::BI__builtin_alloca_uninitialized:
3376 case Builtin::BI__builtin_infer_alloc_token:
3380 case Builtin::BI__arithmetic_fence:
3381 if (BuiltinArithmeticFence(TheCall))
3384 case Builtin::BI__assume:
3385 case Builtin::BI__builtin_assume:
3386 if (BuiltinAssume(TheCall))
3389 case Builtin::BI__builtin_assume_aligned:
3390 if (BuiltinAssumeAligned(TheCall))
3393 case Builtin::BI__builtin_dynamic_object_size:
3394 case Builtin::BI__builtin_object_size:
3398 case Builtin::BI__builtin_longjmp:
3399 if (BuiltinLongjmp(TheCall))
3402 case Builtin::BI__builtin_setjmp:
3403 if (BuiltinSetjmp(TheCall))
3406 case Builtin::BI__builtin_complex:
3407 if (BuiltinComplex(TheCall))
3410 case Builtin::BI__builtin_classify_type:
3411 case Builtin::BI__builtin_constant_p: {
3420 case Builtin::BI__builtin_launder:
3422 case Builtin::BI__builtin_is_within_lifetime:
3424 case Builtin::BI__builtin_trivially_relocate:
3426 case Builtin::BI__builtin_clear_padding: {
3430 const Expr *PtrArg = TheCall->
getArg(0);
3431 const QualType PtrArgType = PtrArg->
getType();
3434 << PtrArgType <<
"pointer" << 1 << 0 << 3 << 1 << PtrArgType
3445 diag::err_typecheck_decl_incomplete_type))
3451 auto IsAddrOfDeclExpr = [&]() {
3453 const auto *UnaryOp = dyn_cast<UnaryOperator>(Inner);
3454 if (!UnaryOp || UnaryOp->getOpcode() != UO_AddrOf)
3458 UnaryOp->getSubExpr()->IgnoreParenNoopCasts(
Context);
3459 const auto *DeclRef = dyn_cast<DeclRefExpr>(Operand);
3463 const auto *VarDecl = dyn_cast<::clang::VarDecl>(DeclRef->getDecl());
3464 if (!VarDecl || VarDecl->getType()->isReferenceType())
3469 QualType VarQType = VarDecl->getType();
3471 Context.hasSameUnqualifiedType(PointeeType, VarQType);
3476 && !IsAddrOfDeclExpr()) {
3477 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_needs_trivial_copy)
3484 Diag(PtrArg->
getBeginLoc(), diag::err_clear_padding_no_flexible_array)
3491 case Builtin::BI__sync_fetch_and_add:
3492 case Builtin::BI__sync_fetch_and_add_1:
3493 case Builtin::BI__sync_fetch_and_add_2:
3494 case Builtin::BI__sync_fetch_and_add_4:
3495 case Builtin::BI__sync_fetch_and_add_8:
3496 case Builtin::BI__sync_fetch_and_add_16:
3497 case Builtin::BI__sync_fetch_and_sub:
3498 case Builtin::BI__sync_fetch_and_sub_1:
3499 case Builtin::BI__sync_fetch_and_sub_2:
3500 case Builtin::BI__sync_fetch_and_sub_4:
3501 case Builtin::BI__sync_fetch_and_sub_8:
3502 case Builtin::BI__sync_fetch_and_sub_16:
3503 case Builtin::BI__sync_fetch_and_or:
3504 case Builtin::BI__sync_fetch_and_or_1:
3505 case Builtin::BI__sync_fetch_and_or_2:
3506 case Builtin::BI__sync_fetch_and_or_4:
3507 case Builtin::BI__sync_fetch_and_or_8:
3508 case Builtin::BI__sync_fetch_and_or_16:
3509 case Builtin::BI__sync_fetch_and_and:
3510 case Builtin::BI__sync_fetch_and_and_1:
3511 case Builtin::BI__sync_fetch_and_and_2:
3512 case Builtin::BI__sync_fetch_and_and_4:
3513 case Builtin::BI__sync_fetch_and_and_8:
3514 case Builtin::BI__sync_fetch_and_and_16:
3515 case Builtin::BI__sync_fetch_and_xor:
3516 case Builtin::BI__sync_fetch_and_xor_1:
3517 case Builtin::BI__sync_fetch_and_xor_2:
3518 case Builtin::BI__sync_fetch_and_xor_4:
3519 case Builtin::BI__sync_fetch_and_xor_8:
3520 case Builtin::BI__sync_fetch_and_xor_16:
3521 case Builtin::BI__sync_fetch_and_nand:
3522 case Builtin::BI__sync_fetch_and_nand_1:
3523 case Builtin::BI__sync_fetch_and_nand_2:
3524 case Builtin::BI__sync_fetch_and_nand_4:
3525 case Builtin::BI__sync_fetch_and_nand_8:
3526 case Builtin::BI__sync_fetch_and_nand_16:
3527 case Builtin::BI__sync_add_and_fetch:
3528 case Builtin::BI__sync_add_and_fetch_1:
3529 case Builtin::BI__sync_add_and_fetch_2:
3530 case Builtin::BI__sync_add_and_fetch_4:
3531 case Builtin::BI__sync_add_and_fetch_8:
3532 case Builtin::BI__sync_add_and_fetch_16:
3533 case Builtin::BI__sync_sub_and_fetch:
3534 case Builtin::BI__sync_sub_and_fetch_1:
3535 case Builtin::BI__sync_sub_and_fetch_2:
3536 case Builtin::BI__sync_sub_and_fetch_4:
3537 case Builtin::BI__sync_sub_and_fetch_8:
3538 case Builtin::BI__sync_sub_and_fetch_16:
3539 case Builtin::BI__sync_and_and_fetch:
3540 case Builtin::BI__sync_and_and_fetch_1:
3541 case Builtin::BI__sync_and_and_fetch_2:
3542 case Builtin::BI__sync_and_and_fetch_4:
3543 case Builtin::BI__sync_and_and_fetch_8:
3544 case Builtin::BI__sync_and_and_fetch_16:
3545 case Builtin::BI__sync_or_and_fetch:
3546 case Builtin::BI__sync_or_and_fetch_1:
3547 case Builtin::BI__sync_or_and_fetch_2:
3548 case Builtin::BI__sync_or_and_fetch_4:
3549 case Builtin::BI__sync_or_and_fetch_8:
3550 case Builtin::BI__sync_or_and_fetch_16:
3551 case Builtin::BI__sync_xor_and_fetch:
3552 case Builtin::BI__sync_xor_and_fetch_1:
3553 case Builtin::BI__sync_xor_and_fetch_2:
3554 case Builtin::BI__sync_xor_and_fetch_4:
3555 case Builtin::BI__sync_xor_and_fetch_8:
3556 case Builtin::BI__sync_xor_and_fetch_16:
3557 case Builtin::BI__sync_nand_and_fetch:
3558 case Builtin::BI__sync_nand_and_fetch_1:
3559 case Builtin::BI__sync_nand_and_fetch_2:
3560 case Builtin::BI__sync_nand_and_fetch_4:
3561 case Builtin::BI__sync_nand_and_fetch_8:
3562 case Builtin::BI__sync_nand_and_fetch_16:
3563 case Builtin::BI__sync_val_compare_and_swap:
3564 case Builtin::BI__sync_val_compare_and_swap_1:
3565 case Builtin::BI__sync_val_compare_and_swap_2:
3566 case Builtin::BI__sync_val_compare_and_swap_4:
3567 case Builtin::BI__sync_val_compare_and_swap_8:
3568 case Builtin::BI__sync_val_compare_and_swap_16:
3569 case Builtin::BI__sync_bool_compare_and_swap:
3570 case Builtin::BI__sync_bool_compare_and_swap_1:
3571 case Builtin::BI__sync_bool_compare_and_swap_2:
3572 case Builtin::BI__sync_bool_compare_and_swap_4:
3573 case Builtin::BI__sync_bool_compare_and_swap_8:
3574 case Builtin::BI__sync_bool_compare_and_swap_16:
3575 case Builtin::BI__sync_lock_test_and_set:
3576 case Builtin::BI__sync_lock_test_and_set_1:
3577 case Builtin::BI__sync_lock_test_and_set_2:
3578 case Builtin::BI__sync_lock_test_and_set_4:
3579 case Builtin::BI__sync_lock_test_and_set_8:
3580 case Builtin::BI__sync_lock_test_and_set_16:
3581 case Builtin::BI__sync_lock_release:
3582 case Builtin::BI__sync_lock_release_1:
3583 case Builtin::BI__sync_lock_release_2:
3584 case Builtin::BI__sync_lock_release_4:
3585 case Builtin::BI__sync_lock_release_8:
3586 case Builtin::BI__sync_lock_release_16:
3587 case Builtin::BI__sync_swap:
3588 case Builtin::BI__sync_swap_1:
3589 case Builtin::BI__sync_swap_2:
3590 case Builtin::BI__sync_swap_4:
3591 case Builtin::BI__sync_swap_8:
3592 case Builtin::BI__sync_swap_16:
3593 return BuiltinAtomicOverloaded(TheCallResult);
3594 case Builtin::BI__sync_synchronize:
3598 case Builtin::BI__builtin_nontemporal_load:
3599 case Builtin::BI__builtin_nontemporal_store:
3600 return BuiltinNontemporalOverloaded(TheCallResult);
3601 case Builtin::BI__builtin_memcpy_inline: {
3602 clang::Expr *SizeOp = TheCall->
getArg(2);
3614 case Builtin::BI__builtin_memset_inline: {
3615 clang::Expr *SizeOp = TheCall->
getArg(2);
3625#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3626 case Builtin::BI##ID: \
3627 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3628#include "clang/Basic/Builtins.inc"
3629 case Builtin::BI__annotation: {
3630 const llvm::Triple &TT =
Context.getTargetInfo().getTriple();
3631 if (!TT.isOSWindows() && !TT.isUEFI()) {
3640 case Builtin::BI__builtin_annotation:
3644 case Builtin::BI__builtin_addressof:
3648 case Builtin::BI__builtin_function_start:
3652 case Builtin::BI__builtin_is_aligned:
3653 case Builtin::BI__builtin_align_up:
3654 case Builtin::BI__builtin_align_down:
3658 case Builtin::BI__builtin_add_overflow:
3659 case Builtin::BI__builtin_sub_overflow:
3660 case Builtin::BI__builtin_mul_overflow:
3664 case Builtin::BI__builtin_operator_new:
3665 case Builtin::BI__builtin_operator_delete: {
3666 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3668 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3671 case Builtin::BI__builtin_dump_struct:
3673 case Builtin::BI__builtin_expect_with_probability: {
3678 const Expr *ProbArg = TheCall->
getArg(2);
3679 SmallVector<PartialDiagnosticAt, 8> Notes;
3680 Expr::EvalResult Eval;
3684 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3691 bool LoseInfo =
false;
3692 Probability.convert(llvm::APFloat::IEEEdouble(),
3693 llvm::RoundingMode::Dynamic, &LoseInfo);
3694 if (!(Probability >= llvm::APFloat(0.0) &&
3695 Probability <= llvm::APFloat(1.0))) {
3702 case Builtin::BI__builtin_preserve_access_index:
3706 case Builtin::BI__builtin_call_with_static_chain:
3710 case Builtin::BI__exception_code:
3711 case Builtin::BI_exception_code:
3713 diag::err_seh___except_block))
3716 case Builtin::BI__exception_info:
3717 case Builtin::BI_exception_info:
3719 diag::err_seh___except_filter))
3722 case Builtin::BI__GetExceptionInfo:
3734 case Builtin::BIaddressof:
3735 case Builtin::BI__addressof:
3736 case Builtin::BIforward:
3737 case Builtin::BIforward_like:
3738 case Builtin::BImove:
3739 case Builtin::BImove_if_noexcept:
3740 case Builtin::BIas_const: {
3748 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3749 BuiltinID == Builtin::BI__addressof;
3751 (ReturnsPointer ?
Result->isAnyPointerType()
3752 :
Result->isReferenceType()) &&
3755 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3761 case Builtin::BI__builtin_ptrauth_strip:
3763 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3765 case Builtin::BI__builtin_ptrauth_sign_constant:
3768 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3771 case Builtin::BI__builtin_ptrauth_auth:
3774 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3776 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3778 case Builtin::BI__builtin_ptrauth_auth_with_pc_and_resign:
3780 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3782 case Builtin::BI__builtin_ptrauth_string_discriminator:
3785 case Builtin::BI__builtin_get_vtable_pointer:
3789 case Builtin::BIread_pipe:
3790 case Builtin::BIwrite_pipe:
3793 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3796 case Builtin::BIreserve_read_pipe:
3797 case Builtin::BIreserve_write_pipe:
3798 case Builtin::BIwork_group_reserve_read_pipe:
3799 case Builtin::BIwork_group_reserve_write_pipe:
3800 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3803 case Builtin::BIsub_group_reserve_read_pipe:
3804 case Builtin::BIsub_group_reserve_write_pipe:
3805 if (
OpenCL().checkSubgroupExt(TheCall) ||
3806 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3809 case Builtin::BIcommit_read_pipe:
3810 case Builtin::BIcommit_write_pipe:
3811 case Builtin::BIwork_group_commit_read_pipe:
3812 case Builtin::BIwork_group_commit_write_pipe:
3813 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3816 case Builtin::BIsub_group_commit_read_pipe:
3817 case Builtin::BIsub_group_commit_write_pipe:
3818 if (
OpenCL().checkSubgroupExt(TheCall) ||
3819 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3822 case Builtin::BIget_pipe_num_packets:
3823 case Builtin::BIget_pipe_max_packets:
3824 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3827 case Builtin::BIto_global:
3828 case Builtin::BIto_local:
3829 case Builtin::BIto_private:
3830 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3834 case Builtin::BIenqueue_kernel:
3835 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3838 case Builtin::BIget_kernel_work_group_size:
3839 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3840 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3843 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3844 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3845 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3848 case Builtin::BI__builtin_os_log_format:
3849 Cleanup.setExprNeedsCleanups(
true);
3851 case Builtin::BI__builtin_os_log_format_buffer_size:
3852 if (BuiltinOSLogFormat(TheCall))
3855 case Builtin::BI__builtin_frame_address:
3856 case Builtin::BI__builtin_return_address: {
3865 Result.Val.getInt() != 0)
3867 << ((BuiltinID == Builtin::BI__builtin_return_address)
3868 ?
"__builtin_return_address"
3869 :
"__builtin_frame_address")
3874 case Builtin::BI__builtin_nondeterministic_value: {
3875 if (BuiltinNonDeterministicValue(TheCall))
3882 case Builtin::BI__builtin_elementwise_abs:
3890 case Builtin::BI__builtin_elementwise_acos:
3891 case Builtin::BI__builtin_elementwise_asin:
3892 case Builtin::BI__builtin_elementwise_atan:
3893 case Builtin::BI__builtin_elementwise_ceil:
3894 case Builtin::BI__builtin_elementwise_cos:
3895 case Builtin::BI__builtin_elementwise_cosh:
3896 case Builtin::BI__builtin_elementwise_exp:
3897 case Builtin::BI__builtin_elementwise_exp2:
3898 case Builtin::BI__builtin_elementwise_exp10:
3899 case Builtin::BI__builtin_elementwise_floor:
3900 case Builtin::BI__builtin_elementwise_log:
3901 case Builtin::BI__builtin_elementwise_log2:
3902 case Builtin::BI__builtin_elementwise_log10:
3903 case Builtin::BI__builtin_elementwise_roundeven:
3904 case Builtin::BI__builtin_elementwise_round:
3905 case Builtin::BI__builtin_elementwise_rint:
3906 case Builtin::BI__builtin_elementwise_nearbyint:
3907 case Builtin::BI__builtin_elementwise_sin:
3908 case Builtin::BI__builtin_elementwise_sinh:
3909 case Builtin::BI__builtin_elementwise_sqrt:
3910 case Builtin::BI__builtin_elementwise_tan:
3911 case Builtin::BI__builtin_elementwise_tanh:
3912 case Builtin::BI__builtin_elementwise_trunc:
3913 case Builtin::BI__builtin_elementwise_canonicalize:
3918 case Builtin::BI__builtin_elementwise_fma:
3923 case Builtin::BI__builtin_elementwise_ldexp: {
3945 const auto *Vec0 = TyA->
getAs<VectorType>();
3946 const auto *Vec1 = TyExp->
getAs<VectorType>();
3947 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3949 if (Arg0Length != Arg1Length) {
3951 diag::err_typecheck_vector_lengths_not_equal)
3965 case Builtin::BI__builtin_elementwise_minnum:
3966 case Builtin::BI__builtin_elementwise_maxnum:
3967 case Builtin::BI__builtin_elementwise_minimum:
3968 case Builtin::BI__builtin_elementwise_maximum:
3969 case Builtin::BI__builtin_elementwise_minimumnum:
3970 case Builtin::BI__builtin_elementwise_maximumnum:
3971 case Builtin::BI__builtin_elementwise_atan2:
3972 case Builtin::BI__builtin_elementwise_fmod:
3973 case Builtin::BI__builtin_elementwise_pow:
3974 if (BuiltinElementwiseMath(TheCall,
3980 case Builtin::BI__builtin_elementwise_add_sat:
3981 case Builtin::BI__builtin_elementwise_sub_sat:
3982 case Builtin::BI__builtin_elementwise_clmul:
3983 case Builtin::BI__builtin_elementwise_pext:
3984 case Builtin::BI__builtin_elementwise_pdep:
3985 if (BuiltinElementwiseMath(TheCall,
3989 case Builtin::BI__builtin_elementwise_fshl:
3990 case Builtin::BI__builtin_elementwise_fshr:
3995 case Builtin::BI__builtin_elementwise_min:
3996 case Builtin::BI__builtin_elementwise_max: {
3997 if (BuiltinElementwiseMath(TheCall))
3999 Expr *Arg0 = TheCall->
getArg(0);
4000 Expr *Arg1 = TheCall->
getArg(1);
4001 QualType Ty0 = Arg0->
getType();
4002 QualType Ty1 = Arg1->
getType();
4003 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
4004 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
4007 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
4008 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
4009 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
4012 case Builtin::BI__builtin_elementwise_popcount:
4013 case Builtin::BI__builtin_elementwise_bitreverse:
4018 case Builtin::BI__builtin_elementwise_copysign: {
4027 QualType MagnitudeTy = Magnitude.
get()->
getType();
4040 diag::err_typecheck_call_different_arg_types)
4041 << MagnitudeTy << SignTy;
4049 case Builtin::BI__builtin_elementwise_clzg:
4050 case Builtin::BI__builtin_elementwise_ctzg:
4058 }
else if (BuiltinElementwiseMath(
4062 case Builtin::BI__builtin_reduce_max:
4063 case Builtin::BI__builtin_reduce_min: {
4064 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4067 const Expr *Arg = TheCall->
getArg(0);
4072 ElTy = TyA->getElementType();
4076 if (ElTy.isNull()) {
4086 case Builtin::BI__builtin_reduce_maximum:
4087 case Builtin::BI__builtin_reduce_minimum: {
4088 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4091 const Expr *Arg = TheCall->
getArg(0);
4096 ElTy = TyA->getElementType();
4100 if (ElTy.isNull() || !ElTy->isFloatingType()) {
4113 case Builtin::BI__builtin_reduce_add:
4114 case Builtin::BI__builtin_reduce_mul:
4115 case Builtin::BI__builtin_reduce_xor:
4116 case Builtin::BI__builtin_reduce_or:
4117 case Builtin::BI__builtin_reduce_and: {
4118 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
4121 const Expr *Arg = TheCall->
getArg(0);
4135 case Builtin::BI__builtin_reduce_assoc_fadd:
4136 case Builtin::BI__builtin_reduce_in_order_fadd: {
4138 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
4163 diag::err_builtin_invalid_arg_type)
4175 case Builtin::BI__builtin_matrix_transpose:
4176 return BuiltinMatrixTranspose(TheCall, TheCallResult);
4178 case Builtin::BI__builtin_matrix_column_major_load:
4179 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
4181 case Builtin::BI__builtin_matrix_column_major_store:
4182 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
4184 case Builtin::BI__builtin_verbose_trap:
4189 case Builtin::BI__builtin_get_device_side_mangled_name: {
4190 auto Check = [](CallExpr *TheCall) {
4196 auto *D = DRE->getDecl();
4199 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
4200 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
4202 if (!Check(TheCall)) {
4204 diag::err_hip_invalid_args_builtin_mangled_name);
4209 case Builtin::BI__builtin_bswapg:
4213 case Builtin::BI__builtin_bitreverseg:
4217 case Builtin::BI__builtin_popcountg:
4221 case Builtin::BI__builtin_clzg:
4222 case Builtin::BI__builtin_ctzg:
4227 case Builtin::BI__builtin_stdc_rotate_left:
4228 case Builtin::BI__builtin_stdc_rotate_right:
4233 case Builtin::BI__builtin_stdc_memreverse8:
4234 case Builtin::BIstdc_memreverse8:
4235 case Builtin::BIstdc_memreverse8u8:
4236 case Builtin::BIstdc_memreverse8u16:
4237 case Builtin::BIstdc_memreverse8u32:
4238 case Builtin::BIstdc_memreverse8u64:
4239 case Builtin::BIstdc_load8_leu8:
4240 case Builtin::BIstdc_load8_leu16:
4241 case Builtin::BIstdc_load8_leu32:
4242 case Builtin::BIstdc_load8_leu64:
4243 case Builtin::BIstdc_load8_les8:
4244 case Builtin::BIstdc_load8_les16:
4245 case Builtin::BIstdc_load8_les32:
4246 case Builtin::BIstdc_load8_les64:
4247 case Builtin::BIstdc_load8_beu8:
4248 case Builtin::BIstdc_load8_beu16:
4249 case Builtin::BIstdc_load8_beu32:
4250 case Builtin::BIstdc_load8_beu64:
4251 case Builtin::BIstdc_load8_bes8:
4252 case Builtin::BIstdc_load8_bes16:
4253 case Builtin::BIstdc_load8_bes32:
4254 case Builtin::BIstdc_load8_bes64:
4255 case Builtin::BIstdc_load8_aligned_leu8:
4256 case Builtin::BIstdc_load8_aligned_leu16:
4257 case Builtin::BIstdc_load8_aligned_leu32:
4258 case Builtin::BIstdc_load8_aligned_leu64:
4259 case Builtin::BIstdc_load8_aligned_les8:
4260 case Builtin::BIstdc_load8_aligned_les16:
4261 case Builtin::BIstdc_load8_aligned_les32:
4262 case Builtin::BIstdc_load8_aligned_les64:
4263 case Builtin::BIstdc_load8_aligned_beu8:
4264 case Builtin::BIstdc_load8_aligned_beu16:
4265 case Builtin::BIstdc_load8_aligned_beu32:
4266 case Builtin::BIstdc_load8_aligned_beu64:
4267 case Builtin::BIstdc_load8_aligned_bes8:
4268 case Builtin::BIstdc_load8_aligned_bes16:
4269 case Builtin::BIstdc_load8_aligned_bes32:
4270 case Builtin::BIstdc_load8_aligned_bes64:
4271 if (
Context.getTargetInfo().getCharWidth() != 8) {
4278 case Builtin::BI__builtin_stdc_bit_floor:
4279 case Builtin::BI__builtin_stdc_bit_ceil:
4283 case Builtin::BI__builtin_stdc_has_single_bit:
4287 case Builtin::BI__builtin_stdc_leading_zeros:
4288 case Builtin::BI__builtin_stdc_leading_ones:
4289 case Builtin::BI__builtin_stdc_trailing_zeros:
4290 case Builtin::BI__builtin_stdc_trailing_ones:
4291 case Builtin::BI__builtin_stdc_first_leading_zero:
4292 case Builtin::BI__builtin_stdc_first_leading_one:
4293 case Builtin::BI__builtin_stdc_first_trailing_zero:
4294 case Builtin::BI__builtin_stdc_first_trailing_one:
4295 case Builtin::BI__builtin_stdc_count_zeros:
4296 case Builtin::BI__builtin_stdc_count_ones:
4297 case Builtin::BI__builtin_stdc_bit_width:
4302 case Builtin::BI__builtin_allow_runtime_check: {
4303 Expr *Arg = TheCall->
getArg(0);
4313 case Builtin::BI__builtin_allow_sanitize_check: {
4317 Expr *Arg = TheCall->
getArg(0);
4319 const StringLiteral *SanitizerName =
4321 if (!SanitizerName) {
4327 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
4328 .Cases({
"address",
"thread",
"memory",
"hwaddress",
4329 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
4333 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
4339 case Builtin::BI__builtin_counted_by_ref:
4340 if (BuiltinCountedByRef(TheCall))
4350 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
4351 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
4352 assert(
Context.getAuxTargetInfo() &&
4353 "Aux Target Builtin, but not an aux target?");
4360 diag::err_builtin_target_unsupported)
4363 if (CheckTSBuiltinFunctionCall(
4365 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
4368 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
4374 return TheCallResult;
4389 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
4393 diag::err_argument_not_contiguous_bit_field)
4400 bool IsVariadic =
false;
4403 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
4404 IsVariadic = BD->isVariadic();
4405 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
4406 IsVariadic = OMD->isVariadic();
4413 bool HasImplicitThisParam,
bool IsVariadic,
4417 else if (IsVariadic)
4427 if (HasImplicitThisParam) {
4459 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4460 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4461 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4462 Expr = ILE->getInit(0);
4472 const Expr *ArgExpr,
4476 S.
PDiag(diag::warn_null_arg)
4482 if (
auto nullability =
type->getNullability())
4493 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4499 llvm::SmallBitVector NonNullArgs;
4505 for (
const auto *Arg : Args)
4512 unsigned IdxAST = Idx.getASTIndex();
4513 if (IdxAST >= Args.size())
4515 if (NonNullArgs.empty())
4516 NonNullArgs.resize(Args.size());
4517 NonNullArgs.set(IdxAST);
4526 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4531 unsigned ParamIndex = 0;
4533 I != E; ++I, ++ParamIndex) {
4536 if (NonNullArgs.empty())
4537 NonNullArgs.resize(Args.size());
4539 NonNullArgs.set(ParamIndex);
4546 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4551 type = blockType->getPointeeType();
4565 if (NonNullArgs.empty())
4566 NonNullArgs.resize(Args.size());
4568 NonNullArgs.set(Index);
4577 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4578 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4579 if (NonNullArgs[ArgIndex])
4585 StringRef ParamName,
QualType ArgTy,
4608 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4609 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4613 if (ArgAlign < ParamAlign)
4614 Diag(Loc, diag::warn_param_mismatched_alignment)
4616 << ParamName << (FDecl !=
nullptr) << FDecl;
4620 const Expr *ThisArg,
4622 if (!FD || Args.empty())
4624 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4625 if (Idx == LifetimeCaptureByAttr::Global ||
4626 Idx == LifetimeCaptureByAttr::Unknown)
4628 if (IsMemberFunction && Idx == 0)
4630 return Args[Idx - IsMemberFunction];
4632 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4637 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4638 for (
int CapturingParamIdx :
Attr->params()) {
4639 if (CapturingParamIdx == LifetimeCaptureByAttr::Invalid)
4643 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4646 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4653 for (
const auto *A :
4655 HandleCaptureByAttr(A, I + IsMemberFunction);
4657 if (IsMemberFunction) {
4665 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4675 llvm::any_of(Args, [](
const Expr *E) {
4676 return E && E->isInstantiationDependent();
4681 llvm::SmallBitVector CheckedVarArgs;
4683 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4685 CheckedVarArgs.resize(Args.size());
4686 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4691 CheckedVarArgs.resize(Args.size());
4692 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4699 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4703 : isa_and_nonnull<FunctionDecl>(FDecl)
4705 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4709 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4711 if (
const Expr *Arg = Args[ArgIdx]) {
4712 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4719 if (FDecl || Proto) {
4724 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4725 CheckArgumentWithTypeTag(I, Args, Loc);
4731 if (!Proto && FDecl) {
4733 if (isa_and_nonnull<FunctionProtoType>(FT))
4739 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4741 bool IsScalableArg =
false;
4742 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4744 if (
const Expr *Arg = Args[ArgIdx]) {
4748 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4756 IsScalableArg =
true;
4758 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4767 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4768 llvm::StringMap<bool> CallerFeatureMap;
4769 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4770 if (!CallerFeatureMap.contains(
"sme"))
4771 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4772 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4773 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4782 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4784 (IsScalableArg || IsScalableRet)) {
4785 bool IsCalleeStreaming =
4787 bool IsCalleeStreamingCompatible =
4791 if (!IsCalleeStreamingCompatible &&
4795 unsigned VL = LO.VScaleMin * 128;
4796 unsigned SVL = LO.VScaleStreamingMin * 128;
4797 bool IsVLMismatch = VL && SVL && VL != SVL;
4799 auto EmitDiag = [&](
bool IsArg) {
4803 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4804 << IsArg << IsCalleeStreaming << SVL << VL;
4807 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4808 << IsArg << SVL << VL;
4810 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4827 bool CallerHasZAState =
false;
4828 bool CallerHasZT0State =
false;
4830 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4832 CallerHasZAState =
true;
4834 CallerHasZT0State =
true;
4838 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4840 CallerHasZT0State |=
4842 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4848 Diag(Loc, diag::err_sme_za_call_no_za_state);
4851 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4855 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4856 Diag(Loc, diag::note_sme_use_preserves_za);
4861 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4862 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4863 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4864 if (!Arg->isValueDependent()) {
4866 if (Arg->EvaluateAsInt(Align,
Context)) {
4867 const llvm::APSInt &I = Align.
Val.
getInt();
4868 if (!I.isPowerOf2())
4869 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4870 << Arg->getSourceRange();
4873 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4882 << diag::OffloadLang::SYCL;
4890 AutoT->getTypeConstraintConcept().getAsTemplateDecl()) {
4905 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4906 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4908 checkCall(FDecl, Proto,
nullptr, Args,
true,
4917 IsMemberOperatorCall;
4923 Expr *ImplicitThis =
nullptr;
4928 ImplicitThis = Args[0];
4931 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4942 ThisType =
Context.getPointerType(ThisType);
4948 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4966 CheckAbsoluteValueFunction(TheCall, FDecl);
4967 CheckMaxUnsignedZero(TheCall, FDecl);
4968 CheckInfNaNFunction(TheCall, FDecl);
4979 case Builtin::BIstrlcpy:
4980 case Builtin::BIstrlcat:
4981 CheckStrlcpycatArguments(TheCall, FnInfo);
4983 case Builtin::BIstrncat:
4984 CheckStrncatArguments(TheCall, FnInfo);
4986 case Builtin::BIfree:
4987 CheckFreeArguments(TheCall);
4990 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4999 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
5000 Ty =
V->getType().getNonReferenceType();
5001 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
5002 Ty = F->getType().getNonReferenceType();
5039 if (!llvm::isValidAtomicOrderingCABI(Ordering))
5042 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
5044 case AtomicExpr::AO__c11_atomic_init:
5045 case AtomicExpr::AO__opencl_atomic_init:
5046 llvm_unreachable(
"There is no ordering argument for an init");
5048 case AtomicExpr::AO__c11_atomic_load:
5049 case AtomicExpr::AO__opencl_atomic_load:
5050 case AtomicExpr::AO__hip_atomic_load:
5051 case AtomicExpr::AO__atomic_load_n:
5052 case AtomicExpr::AO__atomic_load:
5053 case AtomicExpr::AO__scoped_atomic_load_n:
5054 case AtomicExpr::AO__scoped_atomic_load:
5055 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
5056 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
5058 case AtomicExpr::AO__c11_atomic_store:
5059 case AtomicExpr::AO__opencl_atomic_store:
5060 case AtomicExpr::AO__hip_atomic_store:
5061 case AtomicExpr::AO__atomic_store:
5062 case AtomicExpr::AO__atomic_store_n:
5063 case AtomicExpr::AO__scoped_atomic_store:
5064 case AtomicExpr::AO__scoped_atomic_store_n:
5065 case AtomicExpr::AO__atomic_clear:
5066 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
5067 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
5068 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
5098#define HIP_ATOMIC_FIXABLE(hip, scoped) \
5099 case AtomicExpr::AO__hip_atomic_##hip: \
5100 OldName = "__hip_atomic_" #hip; \
5101 NewName = "__scoped_atomic_" #scoped; \
5114#undef HIP_ATOMIC_FIXABLE
5115 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5116 OldName =
"__hip_atomic_compare_exchange_weak";
5117 NewName =
"__scoped_atomic_compare_exchange";
5120 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5121 OldName =
"__hip_atomic_compare_exchange_strong";
5122 NewName =
"__scoped_atomic_compare_exchange";
5126 llvm_unreachable(
"unhandled HIP atomic op");
5129 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
5130 << OldName << NewName;
5137 std::optional<llvm::APSInt> ScopeVal =
5142 StringRef ScopeName;
5143 switch (ScopeVal->getZExtValue()) {
5145 ScopeName =
"__MEMORY_SCOPE_SINGLE";
5148 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
5151 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
5154 ScopeName =
"__MEMORY_SCOPE_DEVICE";
5157 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
5160 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
5212 const unsigned NumForm = ClearByte + 1;
5213 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
5214 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
5222 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
5223 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
5224 "need to update code for modified forms");
5225 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
5226 AtomicExpr::AO__atomic_xor_fetch + 1 ==
5227 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
5228 "need to update code for modified C11 atomics");
5229 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
5230 Op <= AtomicExpr::AO__opencl_atomic_store;
5231 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
5232 Op <= AtomicExpr::AO__hip_atomic_store;
5233 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
5234 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
5235 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
5236 Op <= AtomicExpr::AO__c11_atomic_store) ||
5238 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
5239 Op == AtomicExpr::AO__atomic_store_n ||
5240 Op == AtomicExpr::AO__atomic_exchange_n ||
5241 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
5242 Op == AtomicExpr::AO__scoped_atomic_load_n ||
5243 Op == AtomicExpr::AO__scoped_atomic_store_n ||
5244 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
5245 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
5249 enum ArithOpExtraValueType {
5255 unsigned ArithAllows = AOEVT_None;
5258 case AtomicExpr::AO__c11_atomic_init:
5259 case AtomicExpr::AO__opencl_atomic_init:
5263 case AtomicExpr::AO__c11_atomic_load:
5264 case AtomicExpr::AO__opencl_atomic_load:
5265 case AtomicExpr::AO__hip_atomic_load:
5266 case AtomicExpr::AO__atomic_load_n:
5267 case AtomicExpr::AO__scoped_atomic_load_n:
5268 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5272 case AtomicExpr::AO__atomic_load:
5273 case AtomicExpr::AO__scoped_atomic_load:
5274 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5278 case AtomicExpr::AO__c11_atomic_store:
5279 case AtomicExpr::AO__opencl_atomic_store:
5280 case AtomicExpr::AO__hip_atomic_store:
5281 case AtomicExpr::AO__atomic_store:
5282 case AtomicExpr::AO__atomic_store_n:
5283 case AtomicExpr::AO__scoped_atomic_store:
5284 case AtomicExpr::AO__scoped_atomic_store_n:
5285 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5288 case AtomicExpr::AO__atomic_fetch_add:
5289 case AtomicExpr::AO__atomic_fetch_sub:
5290 case AtomicExpr::AO__atomic_add_fetch:
5291 case AtomicExpr::AO__atomic_sub_fetch:
5292 case AtomicExpr::AO__scoped_atomic_fetch_add:
5293 case AtomicExpr::AO__scoped_atomic_fetch_sub:
5294 case AtomicExpr::AO__scoped_atomic_add_fetch:
5295 case AtomicExpr::AO__scoped_atomic_sub_fetch:
5296 case AtomicExpr::AO__c11_atomic_fetch_add:
5297 case AtomicExpr::AO__c11_atomic_fetch_sub:
5298 case AtomicExpr::AO__opencl_atomic_fetch_add:
5299 case AtomicExpr::AO__opencl_atomic_fetch_sub:
5300 case AtomicExpr::AO__hip_atomic_fetch_add:
5301 case AtomicExpr::AO__hip_atomic_fetch_sub:
5302 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5305 case AtomicExpr::AO__atomic_fetch_fminimum:
5306 case AtomicExpr::AO__atomic_fetch_fmaximum:
5307 case AtomicExpr::AO__atomic_fetch_fminimum_num:
5308 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
5309 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
5310 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
5311 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
5312 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
5313 ArithAllows = AOEVT_FP;
5316 case AtomicExpr::AO__atomic_fetch_max:
5317 case AtomicExpr::AO__atomic_fetch_min:
5318 case AtomicExpr::AO__atomic_max_fetch:
5319 case AtomicExpr::AO__atomic_min_fetch:
5320 case AtomicExpr::AO__scoped_atomic_fetch_max:
5321 case AtomicExpr::AO__scoped_atomic_fetch_min:
5322 case AtomicExpr::AO__scoped_atomic_max_fetch:
5323 case AtomicExpr::AO__scoped_atomic_min_fetch:
5324 case AtomicExpr::AO__c11_atomic_fetch_max:
5325 case AtomicExpr::AO__c11_atomic_fetch_min:
5326 case AtomicExpr::AO__opencl_atomic_fetch_max:
5327 case AtomicExpr::AO__opencl_atomic_fetch_min:
5328 case AtomicExpr::AO__hip_atomic_fetch_max:
5329 case AtomicExpr::AO__hip_atomic_fetch_min:
5330 ArithAllows = AOEVT_Int | AOEVT_FP;
5333 case AtomicExpr::AO__c11_atomic_fetch_and:
5334 case AtomicExpr::AO__c11_atomic_fetch_or:
5335 case AtomicExpr::AO__c11_atomic_fetch_xor:
5336 case AtomicExpr::AO__hip_atomic_fetch_and:
5337 case AtomicExpr::AO__hip_atomic_fetch_or:
5338 case AtomicExpr::AO__hip_atomic_fetch_xor:
5339 case AtomicExpr::AO__c11_atomic_fetch_nand:
5340 case AtomicExpr::AO__opencl_atomic_fetch_and:
5341 case AtomicExpr::AO__opencl_atomic_fetch_or:
5342 case AtomicExpr::AO__opencl_atomic_fetch_xor:
5343 case AtomicExpr::AO__atomic_fetch_and:
5344 case AtomicExpr::AO__atomic_fetch_or:
5345 case AtomicExpr::AO__atomic_fetch_xor:
5346 case AtomicExpr::AO__atomic_fetch_nand:
5347 case AtomicExpr::AO__atomic_and_fetch:
5348 case AtomicExpr::AO__atomic_or_fetch:
5349 case AtomicExpr::AO__atomic_xor_fetch:
5350 case AtomicExpr::AO__atomic_nand_fetch:
5351 case AtomicExpr::AO__atomic_fetch_uinc:
5352 case AtomicExpr::AO__atomic_fetch_udec:
5353 case AtomicExpr::AO__scoped_atomic_fetch_and:
5354 case AtomicExpr::AO__scoped_atomic_fetch_or:
5355 case AtomicExpr::AO__scoped_atomic_fetch_xor:
5356 case AtomicExpr::AO__scoped_atomic_fetch_nand:
5357 case AtomicExpr::AO__scoped_atomic_and_fetch:
5358 case AtomicExpr::AO__scoped_atomic_or_fetch:
5359 case AtomicExpr::AO__scoped_atomic_xor_fetch:
5360 case AtomicExpr::AO__scoped_atomic_nand_fetch:
5361 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
5362 case AtomicExpr::AO__scoped_atomic_fetch_udec:
5366 case AtomicExpr::AO__c11_atomic_exchange:
5367 case AtomicExpr::AO__hip_atomic_exchange:
5368 case AtomicExpr::AO__opencl_atomic_exchange:
5369 case AtomicExpr::AO__atomic_exchange_n:
5370 case AtomicExpr::AO__scoped_atomic_exchange_n:
5371 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5375 case AtomicExpr::AO__atomic_exchange:
5376 case AtomicExpr::AO__scoped_atomic_exchange:
5377 ArithAllows = AOEVT_Pointer | AOEVT_FP;
5381 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
5382 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
5383 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
5384 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
5385 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
5386 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
5390 case AtomicExpr::AO__atomic_compare_exchange:
5391 case AtomicExpr::AO__atomic_compare_exchange_n:
5392 case AtomicExpr::AO__scoped_atomic_compare_exchange:
5393 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
5394 ArithAllows = AOEVT_Pointer;
5398 case AtomicExpr::AO__atomic_test_and_set:
5399 Form = TestAndSetByte;
5402 case AtomicExpr::AO__atomic_clear:
5407 unsigned AdjustedNumArgs = NumArgs[Form];
5408 if ((IsOpenCL || IsHIP || IsScoped) &&
5409 Op != AtomicExpr::AO__opencl_atomic_init)
5412 if (Args.size() < AdjustedNumArgs) {
5413 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
5414 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5417 }
else if (Args.size() > AdjustedNumArgs) {
5418 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
5419 diag::err_typecheck_call_too_many_args)
5420 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
5426 Expr *Ptr = Args[0];
5431 Ptr = ConvertedPtr.
get();
5434 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5435 << Ptr->getType() << 0 << Ptr->getSourceRange();
5444 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5445 << Ptr->getType() << Ptr->getSourceRange();
5450 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5452 << Ptr->getSourceRange();
5456 }
else if (Form != Load && Form != LoadCopy) {
5458 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5459 << Ptr->getType() << Ptr->getSourceRange();
5464 if (Form != TestAndSetByte && Form != ClearByte) {
5467 diag::err_incomplete_type))
5470 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5471 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5472 << Ptr->getType() << 1 << Ptr->getSourceRange();
5481 pointerType->getPointeeType().getCVRQualifiers());
5491 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5492 << 0 << Ptr->getType() << Ptr->getSourceRange();
5501 auto IsAllowedValueType = [&](
QualType ValType,
5502 unsigned AllowedType) ->
bool {
5503 bool IsX87LongDouble =
5505 &
Context.getTargetInfo().getLongDoubleFormat() ==
5506 &llvm::APFloat::x87DoubleExtended();
5510 return (AllowedType & AOEVT_Int) || AllowedType != AOEVT_FP;
5512 return AllowedType & AOEVT_Pointer;
5516 if (IsX87LongDouble)
5520 if (!IsAllowedValueType(ValType, ArithAllows)) {
5522 ArithAllows == AOEVT_FP
5523 ? diag::err_atomic_op_needs_atomic_fp
5524 : (ArithAllows & AOEVT_FP
5525 ? (ArithAllows & AOEVT_Pointer
5526 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5527 : diag::err_atomic_op_needs_atomic_int_or_fp)
5528 : (ArithAllows & AOEVT_Pointer
5529 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5530 : diag::err_atomic_op_needs_atomic_int));
5532 << IsC11 << Ptr->getType() << Ptr->getSourceRange();
5537 diag::err_incomplete_type)) {
5548 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5549 << Ptr->getType() << Ptr->getSourceRange();
5564 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5565 << ValType << Ptr->getSourceRange();
5576 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5579 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5585 bool IsPassedByAddress =
false;
5586 if (!IsC11 && !IsHIP && !IsN) {
5587 ByValType = Ptr->getType();
5588 IsPassedByAddress =
true;
5593 APIOrderedArgs.push_back(Args[0]);
5597 APIOrderedArgs.push_back(Args[1]);
5603 APIOrderedArgs.push_back(Args[2]);
5604 APIOrderedArgs.push_back(Args[1]);
5607 APIOrderedArgs.push_back(Args[2]);
5608 APIOrderedArgs.push_back(Args[3]);
5609 APIOrderedArgs.push_back(Args[1]);
5612 APIOrderedArgs.push_back(Args[2]);
5613 APIOrderedArgs.push_back(Args[4]);
5614 APIOrderedArgs.push_back(Args[1]);
5615 APIOrderedArgs.push_back(Args[3]);
5618 APIOrderedArgs.push_back(Args[2]);
5619 APIOrderedArgs.push_back(Args[4]);
5620 APIOrderedArgs.push_back(Args[5]);
5621 APIOrderedArgs.push_back(Args[1]);
5622 APIOrderedArgs.push_back(Args[3]);
5624 case TestAndSetByte:
5626 APIOrderedArgs.push_back(Args[1]);
5630 APIOrderedArgs.append(Args.begin(), Args.end());
5637 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5639 if (i < NumVals[Form] + 1) {
5652 assert(Form != Load);
5654 Ty =
Context.getPointerDiffType();
5657 else if (Form ==
Copy || Form == Xchg) {
5658 if (IsPassedByAddress) {
5665 Expr *ValArg = APIOrderedArgs[i];
5672 AS = PtrTy->getPointeeType().getAddressSpace();
5681 if (IsPassedByAddress)
5701 APIOrderedArgs[i] = Arg.
get();
5706 SubExprs.push_back(Ptr);
5710 SubExprs.push_back(APIOrderedArgs[1]);
5713 case TestAndSetByte:
5715 SubExprs.push_back(APIOrderedArgs[1]);
5721 SubExprs.push_back(APIOrderedArgs[2]);
5722 SubExprs.push_back(APIOrderedArgs[1]);
5726 SubExprs.push_back(APIOrderedArgs[3]);
5727 SubExprs.push_back(APIOrderedArgs[1]);
5728 SubExprs.push_back(APIOrderedArgs[2]);
5731 SubExprs.push_back(APIOrderedArgs[3]);
5732 SubExprs.push_back(APIOrderedArgs[1]);
5733 SubExprs.push_back(APIOrderedArgs[4]);
5734 SubExprs.push_back(APIOrderedArgs[2]);
5737 SubExprs.push_back(APIOrderedArgs[4]);
5738 SubExprs.push_back(APIOrderedArgs[1]);
5739 SubExprs.push_back(APIOrderedArgs[5]);
5740 SubExprs.push_back(APIOrderedArgs[2]);
5741 SubExprs.push_back(APIOrderedArgs[3]);
5746 if (SubExprs.size() >= 2 && Form !=
Init) {
5747 std::optional<llvm::APSInt>
Success =
5748 SubExprs[1]->getIntegerConstantExpr(
Context);
5750 Diag(SubExprs[1]->getBeginLoc(),
5751 diag::warn_atomic_op_has_invalid_memory_order)
5752 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5753 << SubExprs[1]->getSourceRange();
5755 if (SubExprs.size() >= 5) {
5756 if (std::optional<llvm::APSInt>
Failure =
5757 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5758 if (!llvm::is_contained(
5759 {llvm::AtomicOrderingCABI::relaxed,
5760 llvm::AtomicOrderingCABI::consume,
5761 llvm::AtomicOrderingCABI::acquire,
5762 llvm::AtomicOrderingCABI::seq_cst},
5763 (llvm::AtomicOrderingCABI)
Failure->getSExtValue())) {
5764 Diag(SubExprs[3]->getBeginLoc(),
5765 diag::warn_atomic_op_has_invalid_memory_order)
5766 << 2 << SubExprs[3]->getSourceRange();
5773 auto *
Scope = Args[Args.size() - 1];
5774 if (std::optional<llvm::APSInt>
Result =
5776 if (!ScopeModel->isValid(
Result->getZExtValue()))
5777 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5778 <<
Scope->getSourceRange();
5780 SubExprs.push_back(
Scope);
5789 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5790 Op == AtomicExpr::AO__c11_atomic_store ||
5791 Op == AtomicExpr::AO__opencl_atomic_load ||
5792 Op == AtomicExpr::AO__hip_atomic_load ||
5793 Op == AtomicExpr::AO__opencl_atomic_store ||
5794 Op == AtomicExpr::AO__hip_atomic_store) &&
5795 Context.AtomicUsesUnsupportedLibcall(AE))
5797 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5798 Op == AtomicExpr::AO__opencl_atomic_load ||
5799 Op == AtomicExpr::AO__hip_atomic_load)
5804 Diag(Ptr->getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5820 assert(Fn &&
"builtin call without direct callee!");
5836 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5843 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5845 <<
Callee->getSourceRange();
5854 Expr *FirstArg = TheCall->
getArg(0);
5858 FirstArg = FirstArgResult.
get();
5859 TheCall->
setArg(0, FirstArg);
5871 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5878 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5909 QualType ResultType = ValType;
5914#define BUILTIN_ROW(x) \
5915 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5916 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5918 static const unsigned BuiltinIndices[][5] = {
5943 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5944 case 1: SizeIndex = 0;
break;
5945 case 2: SizeIndex = 1;
break;
5946 case 4: SizeIndex = 2;
break;
5947 case 8: SizeIndex = 3;
break;
5948 case 16: SizeIndex = 4;
break;
5960 unsigned BuiltinIndex, NumFixed = 1;
5961 bool WarnAboutSemanticsChange =
false;
5962 switch (BuiltinID) {
5963 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5964 case Builtin::BI__sync_fetch_and_add:
5965 case Builtin::BI__sync_fetch_and_add_1:
5966 case Builtin::BI__sync_fetch_and_add_2:
5967 case Builtin::BI__sync_fetch_and_add_4:
5968 case Builtin::BI__sync_fetch_and_add_8:
5969 case Builtin::BI__sync_fetch_and_add_16:
5973 case Builtin::BI__sync_fetch_and_sub:
5974 case Builtin::BI__sync_fetch_and_sub_1:
5975 case Builtin::BI__sync_fetch_and_sub_2:
5976 case Builtin::BI__sync_fetch_and_sub_4:
5977 case Builtin::BI__sync_fetch_and_sub_8:
5978 case Builtin::BI__sync_fetch_and_sub_16:
5982 case Builtin::BI__sync_fetch_and_or:
5983 case Builtin::BI__sync_fetch_and_or_1:
5984 case Builtin::BI__sync_fetch_and_or_2:
5985 case Builtin::BI__sync_fetch_and_or_4:
5986 case Builtin::BI__sync_fetch_and_or_8:
5987 case Builtin::BI__sync_fetch_and_or_16:
5991 case Builtin::BI__sync_fetch_and_and:
5992 case Builtin::BI__sync_fetch_and_and_1:
5993 case Builtin::BI__sync_fetch_and_and_2:
5994 case Builtin::BI__sync_fetch_and_and_4:
5995 case Builtin::BI__sync_fetch_and_and_8:
5996 case Builtin::BI__sync_fetch_and_and_16:
6000 case Builtin::BI__sync_fetch_and_xor:
6001 case Builtin::BI__sync_fetch_and_xor_1:
6002 case Builtin::BI__sync_fetch_and_xor_2:
6003 case Builtin::BI__sync_fetch_and_xor_4:
6004 case Builtin::BI__sync_fetch_and_xor_8:
6005 case Builtin::BI__sync_fetch_and_xor_16:
6009 case Builtin::BI__sync_fetch_and_nand:
6010 case Builtin::BI__sync_fetch_and_nand_1:
6011 case Builtin::BI__sync_fetch_and_nand_2:
6012 case Builtin::BI__sync_fetch_and_nand_4:
6013 case Builtin::BI__sync_fetch_and_nand_8:
6014 case Builtin::BI__sync_fetch_and_nand_16:
6016 WarnAboutSemanticsChange =
true;
6019 case Builtin::BI__sync_add_and_fetch:
6020 case Builtin::BI__sync_add_and_fetch_1:
6021 case Builtin::BI__sync_add_and_fetch_2:
6022 case Builtin::BI__sync_add_and_fetch_4:
6023 case Builtin::BI__sync_add_and_fetch_8:
6024 case Builtin::BI__sync_add_and_fetch_16:
6028 case Builtin::BI__sync_sub_and_fetch:
6029 case Builtin::BI__sync_sub_and_fetch_1:
6030 case Builtin::BI__sync_sub_and_fetch_2:
6031 case Builtin::BI__sync_sub_and_fetch_4:
6032 case Builtin::BI__sync_sub_and_fetch_8:
6033 case Builtin::BI__sync_sub_and_fetch_16:
6037 case Builtin::BI__sync_and_and_fetch:
6038 case Builtin::BI__sync_and_and_fetch_1:
6039 case Builtin::BI__sync_and_and_fetch_2:
6040 case Builtin::BI__sync_and_and_fetch_4:
6041 case Builtin::BI__sync_and_and_fetch_8:
6042 case Builtin::BI__sync_and_and_fetch_16:
6046 case Builtin::BI__sync_or_and_fetch:
6047 case Builtin::BI__sync_or_and_fetch_1:
6048 case Builtin::BI__sync_or_and_fetch_2:
6049 case Builtin::BI__sync_or_and_fetch_4:
6050 case Builtin::BI__sync_or_and_fetch_8:
6051 case Builtin::BI__sync_or_and_fetch_16:
6055 case Builtin::BI__sync_xor_and_fetch:
6056 case Builtin::BI__sync_xor_and_fetch_1:
6057 case Builtin::BI__sync_xor_and_fetch_2:
6058 case Builtin::BI__sync_xor_and_fetch_4:
6059 case Builtin::BI__sync_xor_and_fetch_8:
6060 case Builtin::BI__sync_xor_and_fetch_16:
6064 case Builtin::BI__sync_nand_and_fetch:
6065 case Builtin::BI__sync_nand_and_fetch_1:
6066 case Builtin::BI__sync_nand_and_fetch_2:
6067 case Builtin::BI__sync_nand_and_fetch_4:
6068 case Builtin::BI__sync_nand_and_fetch_8:
6069 case Builtin::BI__sync_nand_and_fetch_16:
6071 WarnAboutSemanticsChange =
true;
6074 case Builtin::BI__sync_val_compare_and_swap:
6075 case Builtin::BI__sync_val_compare_and_swap_1:
6076 case Builtin::BI__sync_val_compare_and_swap_2:
6077 case Builtin::BI__sync_val_compare_and_swap_4:
6078 case Builtin::BI__sync_val_compare_and_swap_8:
6079 case Builtin::BI__sync_val_compare_and_swap_16:
6084 case Builtin::BI__sync_bool_compare_and_swap:
6085 case Builtin::BI__sync_bool_compare_and_swap_1:
6086 case Builtin::BI__sync_bool_compare_and_swap_2:
6087 case Builtin::BI__sync_bool_compare_and_swap_4:
6088 case Builtin::BI__sync_bool_compare_and_swap_8:
6089 case Builtin::BI__sync_bool_compare_and_swap_16:
6095 case Builtin::BI__sync_lock_test_and_set:
6096 case Builtin::BI__sync_lock_test_and_set_1:
6097 case Builtin::BI__sync_lock_test_and_set_2:
6098 case Builtin::BI__sync_lock_test_and_set_4:
6099 case Builtin::BI__sync_lock_test_and_set_8:
6100 case Builtin::BI__sync_lock_test_and_set_16:
6104 case Builtin::BI__sync_lock_release:
6105 case Builtin::BI__sync_lock_release_1:
6106 case Builtin::BI__sync_lock_release_2:
6107 case Builtin::BI__sync_lock_release_4:
6108 case Builtin::BI__sync_lock_release_8:
6109 case Builtin::BI__sync_lock_release_16:
6115 case Builtin::BI__sync_swap:
6116 case Builtin::BI__sync_swap_1:
6117 case Builtin::BI__sync_swap_2:
6118 case Builtin::BI__sync_swap_4:
6119 case Builtin::BI__sync_swap_8:
6120 case Builtin::BI__sync_swap_16:
6128 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
6129 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
6130 <<
Callee->getSourceRange();
6134 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
6135 <<
Callee->getSourceRange();
6137 if (WarnAboutSemanticsChange) {
6138 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
6139 <<
Callee->getSourceRange();
6144 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
6145 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
6146 FunctionDecl *NewBuiltinDecl;
6147 if (NewBuiltinID == BuiltinID)
6148 NewBuiltinDecl = FDecl;
6151 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
6154 assert(Res.getFoundDecl());
6155 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
6156 if (!NewBuiltinDecl)
6163 for (
unsigned i = 0; i != NumFixed; ++i) {
6192 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
6194 CK_BuiltinFnToFnPtr);
6205 const auto *BitIntValType = ValType->
getAs<BitIntType>();
6206 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
6207 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
6211 return TheCallResult;
6215 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
6220 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
6221 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
6222 "Unexpected nontemporal load/store builtin!");
6223 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
6224 unsigned numArgs = isStore ? 2 : 1;
6234 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
6240 PointerArg = PointerArgResult.
get();
6241 TheCall->
setArg(numArgs - 1, PointerArg);
6245 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
6258 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
6265 return TheCallResult;
6277 return TheCallResult;
6284 auto *
Literal = dyn_cast<StringLiteral>(Arg);
6286 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
6287 Literal = ObjcLiteral->getString();
6291 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
6298 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
6299 InitializedEntity Entity =
6309 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
6310 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
6311 TT.getArch() == llvm::Triple::aarch64_32);
6312 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
6313 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
6314 if (IsX64 || IsAArch64) {
6321 return S.
Diag(Fn->getBeginLoc(),
6322 diag::err_ms_va_start_used_in_sysv_function);
6329 (!IsWindowsOrUEFI && CC ==
CC_Win64))
6330 return S.
Diag(Fn->getBeginLoc(),
6331 diag::err_va_start_used_in_wrong_abi_function)
6332 << !IsWindowsOrUEFI;
6338 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
6346 bool IsVariadic =
false;
6350 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
6351 IsVariadic =
Block->isVariadic();
6352 Params =
Block->parameters();
6353 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
6356 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
6357 IsVariadic = MD->isVariadic();
6359 Params = MD->parameters();
6362 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
6366 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
6371 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
6376 *LastParam = Params.empty() ?
nullptr : Params.back();
6381bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
6386 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
6410 ParmVarDecl *LastParam;
6421 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
6423 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6428 if (std::optional<llvm::APSInt> Val =
6430 Val &&
LangOpts.C23 && *Val == 0 &&
6431 BuiltinID != Builtin::BI__builtin_c23_va_start) {
6432 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
6439 SourceLocation ParamLoc;
6440 bool IsCRegister =
false;
6441 bool SecondArgIsLastNonVariadicArgument =
false;
6442 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6443 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6444 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6447 ParamLoc = PV->getLocation();
6453 if (!SecondArgIsLastNonVariadicArgument)
6455 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6456 else if (IsCRegister ||
Type->isReferenceType() ||
6457 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6460 if (!Context.isPromotableIntegerType(Type))
6462 const auto *ED = Type->getAsEnumDecl();
6465 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6467 unsigned Reason = 0;
6468 if (
Type->isReferenceType()) Reason = 1;
6469 else if (IsCRegister) Reason = 2;
6470 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6471 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6478 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6498 if (
Call->getNumArgs() < 3)
6500 diag::err_typecheck_call_too_few_args_at_least)
6501 << 0 << 3 <<
Call->getNumArgs()
6517 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6520 const QualType &ConstCharPtrTy =
6522 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6524 << Arg1->
getType() << ConstCharPtrTy << 1
6527 << 2 << Arg1->
getType() << ConstCharPtrTy;
6529 const QualType SizeTy =
Context.getSizeType();
6534 << Arg2->
getType() << SizeTy << 1
6537 << 3 << Arg2->
getType() << SizeTy;
6542bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6546 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6574 diag::err_typecheck_call_invalid_ordered_compare)
6582bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6583 unsigned BuiltinID) {
6588 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6589 BuiltinID == Builtin::BI__builtin_isinf ||
6590 BuiltinID == Builtin::BI__builtin_isinf_sign))
6594 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6595 BuiltinID == Builtin::BI__builtin_isunordered))
6599 bool IsFPClass = NumArgs == 2;
6602 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6606 for (
unsigned i = 0; i < FPArgNo; ++i) {
6607 Expr *Arg = TheCall->
getArg(i);
6620 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6629 OrigArg = Res.
get();
6631 TheCall->
setArg(FPArgNo, OrigArg);
6633 QualType VectorResultTy;
6634 QualType ElementTy = OrigArg->
getType();
6639 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6645 diag::err_typecheck_call_invalid_unary_fp)
6658 TheCall->
setArg(NumArgs - 1, MaskRes.
get());
6664 if (!VectorResultTy.
isNull())
6665 ResultTy = VectorResultTy;
6674bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6679 for (
unsigned I = 0; I != 2; ++I) {
6680 Expr *Arg = TheCall->
getArg(I);
6690 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6705 Expr *Real = TheCall->
getArg(0);
6706 Expr *Imag = TheCall->
getArg(1);
6709 diag::err_typecheck_call_different_arg_types)
6724 diag::err_typecheck_call_too_few_args_at_least)
6725 << 0 << 2 << NumArgs
6732 unsigned NumElements = 0;
6747 unsigned NumResElements = NumArgs - 2;
6754 if (RHSVecType->getElementType()->isBooleanType() ||
6755 !RHSVecType->getElementType()->isIntegerType()) {
6764 if (RHSVecType->getNumElements() != NumElements)
6766 diag::err_typecheck_vector_lengths_not_equal)
6767 << LHSType << RHSType <<
false
6770 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6772 diag::err_vec_builtin_incompatible_vector)
6777 }
else if (NumElements != NumResElements) {
6780 ?
Context.getExtVectorType(EltType, NumResElements)
6781 :
Context.getVectorType(EltType, NumResElements,
6786 for (
unsigned I = 2; I != NumArgs; ++I) {
6794 diag::err_shufflevector_nonconstant_argument)
6800 else if (
Result->getActiveBits() > 64 ||
6801 Result->getZExtValue() >= NumElements * 2)
6803 diag::err_shufflevector_argument_too_large)
6828 diag::err_convertvector_non_vector)
6831 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6833 <<
"__builtin_convertvector");
6838 if (SrcElts != DstElts)
6840 diag::err_convertvector_incompatible_vector)
6848bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6853 diag::err_typecheck_call_too_many_args_at_most)
6854 << 0 << 3 << NumArgs << 0
6859 for (
unsigned i = 1; i != NumArgs; ++i) {
6869bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6870 if (!
Context.getTargetInfo().checkArithmeticFenceSupported())
6871 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6875 Expr *Arg = TheCall->
getArg(0);
6879 QualType ArgTy = Arg->
getType();
6881 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6891bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6892 Expr *Arg = TheCall->
getArg(0);
6903bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6905 Expr *Arg = TheCall->
getArg(1);
6909 if (
const auto *UE =
6911 if (UE->getKind() == UETT_AlignOf ||
6912 UE->getKind() == UETT_PreferredAlignOf)
6918 if (!
Result.isPowerOf2())
6919 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6926 if (
Result > std::numeric_limits<int32_t>::max())
6934bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6939 Expr *FirstArg = TheCall->
getArg(0);
6947 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6951 TheCall->
setArg(0, FirstArgResult.
get());
6955 Expr *SecondArg = TheCall->
getArg(1);
6963 if (!
Result.isPowerOf2())
6964 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6976 Expr *ThirdArg = TheCall->
getArg(2);
6979 TheCall->
setArg(2, ThirdArg);
6985bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6986 unsigned BuiltinID =
6988 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6991 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6992 if (NumArgs < NumRequiredArgs) {
6993 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6994 << 0 << NumRequiredArgs << NumArgs
6997 if (NumArgs >= NumRequiredArgs + 0x100) {
6999 diag::err_typecheck_call_too_many_args_at_most)
7000 << 0 << (NumRequiredArgs + 0xff) << NumArgs
7011 if (Arg.isInvalid())
7013 TheCall->
setArg(i, Arg.get());
7018 unsigned FormatIdx = i;
7028 unsigned FirstDataArg = i;
7029 while (i < NumArgs) {
7047 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
7049 bool Success = CheckFormatArguments(
7052 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
7076 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
7085 int High,
bool RangeIsError) {
7099 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
7107 PDiag(diag::warn_argument_invalid_range)
7150 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
7155 if (
Value.isNegative())
7166 if ((
Value & 0xFF) != 0)
7191 Result.setIsUnsigned(
true);
7196 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
7216 Result.setIsUnsigned(
true);
7224 diag::err_argument_not_shifted_byte_or_xxff)
7228bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
7229 if (!Context.getTargetInfo().hasSjLjLowering())
7230 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
7241 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
7247bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
7248 if (!Context.getTargetInfo().hasSjLjLowering())
7249 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
7254bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
7269 diag::err_builtin_counted_by_ref_invalid_arg)
7274 diag::err_builtin_counted_by_ref_has_side_effects)
7277 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
7279 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
7284 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
7285 if (CountFD->isBitField()) {
7286 Diag(ME->getBeginLoc(),
7287 diag::err_builtin_counted_by_ref_counter_field_is_bitfield)
7289 return Diag(CountFD->getBeginLoc(),
7290 diag::note_counted_by_counter_field)
7291 << CountFD << CountFD->getSourceRange();
7300 QualType MemberTy = ME->getMemberDecl()->getType();
7303 diag::err_builtin_counted_by_ref_invalid_arg)
7307 diag::err_builtin_counted_by_ref_invalid_arg)
7317bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
7319 const CallExpr *CE =
7328 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7333 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7338 diag::err_builtin_counted_by_ref_cannot_leak_reference)
7342 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7346 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
7356class UncoveredArgHandler {
7357 enum {
Unknown = -1, AllCovered = -2 };
7359 signed FirstUncoveredArg =
Unknown;
7360 SmallVector<const Expr *, 4> DiagnosticExprs;
7363 UncoveredArgHandler() =
default;
7365 bool hasUncoveredArg()
const {
7366 return (FirstUncoveredArg >= 0);
7369 unsigned getUncoveredArg()
const {
7370 assert(hasUncoveredArg() &&
"no uncovered argument");
7371 return FirstUncoveredArg;
7374 void setAllCovered() {
7377 DiagnosticExprs.clear();
7378 FirstUncoveredArg = AllCovered;
7381 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
7382 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
7385 if (FirstUncoveredArg == AllCovered)
7390 if (NewFirstUncoveredArg == FirstUncoveredArg)
7391 DiagnosticExprs.push_back(StrExpr);
7392 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
7393 DiagnosticExprs.clear();
7394 DiagnosticExprs.push_back(StrExpr);
7395 FirstUncoveredArg = NewFirstUncoveredArg;
7399 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
7402enum StringLiteralCheckType {
7404 SLCT_UncheckedLiteral,
7412 bool AddendIsRight) {
7413 unsigned BitWidth = Offset.getBitWidth();
7414 unsigned AddendBitWidth = Addend.getBitWidth();
7416 if (Addend.isUnsigned()) {
7417 Addend = Addend.zext(++AddendBitWidth);
7418 Addend.setIsSigned(
true);
7421 if (AddendBitWidth > BitWidth) {
7422 Offset = Offset.sext(AddendBitWidth);
7423 BitWidth = AddendBitWidth;
7424 }
else if (BitWidth > AddendBitWidth) {
7425 Addend = Addend.sext(BitWidth);
7429 llvm::APSInt ResOffset = Offset;
7430 if (BinOpKind == BO_Add)
7431 ResOffset = Offset.sadd_ov(Addend, Ov);
7433 assert(AddendIsRight && BinOpKind == BO_Sub &&
7434 "operator must be add or sub with addend on the right");
7435 ResOffset = Offset.ssub_ov(Addend, Ov);
7441 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
7442 "index (intermediate) result too big");
7443 Offset = Offset.sext(2 * BitWidth);
7444 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
7448 Offset = std::move(ResOffset);
7456class FormatStringLiteral {
7457 const StringLiteral *FExpr;
7461 FormatStringLiteral(
const StringLiteral *fexpr,
int64_t Offset = 0)
7462 : FExpr(fexpr), Offset(Offset) {}
7464 const StringLiteral *getFormatString()
const {
return FExpr; }
7466 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7468 unsigned getByteLength()
const {
7469 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7472 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7479 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7480 bool isWide()
const {
return FExpr->
isWide(); }
7481 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7482 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7483 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7484 bool isPascal()
const {
return FExpr->
isPascal(); }
7486 SourceLocation getLocationOfByte(
7487 unsigned ByteNo,
const SourceManager &SM,
const LangOptions &Features,
7488 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7489 unsigned *StartTokenByteOffset =
nullptr)
const {
7491 StartToken, StartTokenByteOffset);
7494 SourceLocation getBeginLoc() const LLVM_READONLY {
7498 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7504 Sema &S,
const FormatStringLiteral *FExpr,
7509 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7510 bool IgnoreStringsWithoutSpecifiers);
7519static StringLiteralCheckType
7525 llvm::SmallBitVector &CheckedVarArgs,
7526 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7527 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7528 bool IgnoreStringsWithoutSpecifiers =
false) {
7530 return SLCT_NotALiteral;
7532 assert(Offset.isSigned() &&
"invalid offset");
7535 return SLCT_NotALiteral;
7544 return SLCT_UncheckedLiteral;
7547 case Stmt::InitListExprClass:
7551 format_idx, firstDataArg,
Type, CallType,
7552 false, CheckedVarArgs,
7553 UncoveredArg, Offset, CallerFormatParamIdx,
7554 IgnoreStringsWithoutSpecifiers);
7556 return SLCT_NotALiteral;
7557 case Stmt::BinaryConditionalOperatorClass:
7558 case Stmt::ConditionalOperatorClass: {
7567 bool CheckLeft =
true, CheckRight =
true;
7570 if (
C->getCond()->EvaluateAsBooleanCondition(
7582 StringLiteralCheckType Left;
7584 Left = SLCT_UncheckedLiteral;
7587 Args, APK, format_idx, firstDataArg,
Type,
7588 CallType, InFunctionCall, CheckedVarArgs,
7589 UncoveredArg, Offset, CallerFormatParamIdx,
7590 IgnoreStringsWithoutSpecifiers);
7591 if (Left == SLCT_NotALiteral || !CheckRight) {
7597 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7598 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7599 UncoveredArg, Offset, CallerFormatParamIdx,
7600 IgnoreStringsWithoutSpecifiers);
7602 return (CheckLeft && Left < Right) ? Left : Right;
7605 case Stmt::ImplicitCastExprClass:
7609 case Stmt::OpaqueValueExprClass:
7614 return SLCT_NotALiteral;
7616 case Stmt::PredefinedExprClass:
7620 return SLCT_UncheckedLiteral;
7622 case Stmt::DeclRefExprClass: {
7628 bool isConstant =
false;
7632 isConstant = AT->getElementType().isConstant(S.
Context);
7634 isConstant =
T.isConstant(S.
Context) &&
7635 PT->getPointeeType().isConstant(S.
Context);
7636 }
else if (
T->isObjCObjectPointerType()) {
7639 isConstant =
T.isConstant(S.
Context);
7643 if (
const Expr *
Init = VD->getAnyInitializer()) {
7646 if (InitList->isStringLiteralInit())
7647 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7650 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7651 firstDataArg,
Type, CallType,
false,
7652 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7703 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7704 if (CallerFormatParamIdx)
7705 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7706 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7707 for (
const auto *PVFormatMatches :
7708 D->specific_attrs<FormatMatchesAttr>()) {
7713 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7717 S.
Diag(Args[format_idx]->getBeginLoc(),
7718 diag::warn_format_string_type_incompatible)
7719 << PVFormatMatches->getType()->getName()
7721 if (!InFunctionCall) {
7722 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7723 diag::note_format_string_defined);
7725 return SLCT_UncheckedLiteral;
7728 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7729 Args, APK, format_idx, firstDataArg,
Type, CallType,
7730 false, CheckedVarArgs, UncoveredArg,
7731 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7735 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7738 PVFormat->getFirstArg(), &CallerFSI))
7740 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7744 S.
Diag(Args[format_idx]->getBeginLoc(),
7745 diag::warn_format_string_type_incompatible)
7746 << PVFormat->getType()->getName()
7748 if (!InFunctionCall) {
7751 return SLCT_UncheckedLiteral;
7764 return SLCT_UncheckedLiteral;
7772 return SLCT_NotALiteral;
7775 case Stmt::CallExprClass:
7776 case Stmt::CXXMemberCallExprClass: {
7780 StringLiteralCheckType CommonResult;
7781 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7782 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7784 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7785 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7786 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7793 return CommonResult;
7795 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7797 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7798 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7801 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7802 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7803 UncoveredArg, Offset, CallerFormatParamIdx,
7804 IgnoreStringsWithoutSpecifiers);
7810 format_idx, firstDataArg,
Type, CallType,
7811 false, CheckedVarArgs,
7812 UncoveredArg, Offset, CallerFormatParamIdx,
7813 IgnoreStringsWithoutSpecifiers);
7814 return SLCT_NotALiteral;
7816 case Stmt::ObjCMessageExprClass: {
7818 if (
const auto *MD = ME->getMethodDecl()) {
7819 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7828 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7830 MD->getSelector().isKeywordSelector(
7831 {
"localizedStringForKey",
"value",
"table"})) {
7832 IgnoreStringsWithoutSpecifiers =
true;
7835 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7837 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7838 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7839 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7843 return SLCT_NotALiteral;
7845 case Stmt::ObjCStringLiteralClass:
7846 case Stmt::StringLiteralClass: {
7855 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7858 return SLCT_NotALiteral;
7860 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7862 format_idx, firstDataArg,
Type, InFunctionCall,
7863 CallType, CheckedVarArgs, UncoveredArg,
7864 IgnoreStringsWithoutSpecifiers);
7865 return SLCT_CheckedLiteral;
7868 return SLCT_NotALiteral;
7870 case Stmt::BinaryOperatorClass: {
7884 if (LIsInt != RIsInt) {
7888 if (BinOpKind == BO_Add) {
7901 return SLCT_NotALiteral;
7903 case Stmt::UnaryOperatorClass: {
7905 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7906 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7908 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7918 return SLCT_NotALiteral;
7922 return SLCT_NotALiteral;
7933 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7934 if (isa_and_nonnull<StringLiteral>(LVE))
7955 return "freebsd_kprintf";
7964 return llvm::StringSwitch<FormatStringType>(Flavor)
7966 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7971 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7987bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7991 llvm::SmallBitVector &CheckedVarArgs) {
7992 FormatStringInfo FSI;
7996 return CheckFormatArguments(
7997 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
8002bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
8006 llvm::SmallBitVector &CheckedVarArgs) {
8007 FormatStringInfo FSI;
8011 return CheckFormatArguments(Args, FSI.ArgPassingKind,
8012 Format->getFormatString(), FSI.FormatIdx,
8014 CallType, Loc, Range, CheckedVarArgs);
8022 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
8035 unsigned CallerArgumentIndexOffset =
8038 unsigned FirstArgumentIndex = -1;
8048 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
8049 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
8053 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
8054 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
8056 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
8059 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
8060 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
8063 FirstArgumentIndex =
8064 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
8070 ? (NumCallerParams + CallerArgumentIndexOffset)
8075 if (!ReferenceFormatString)
8081 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
8083 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
8085 std::string
Attr, Fixit;
8086 llvm::raw_string_ostream AttrOS(
Attr);
8088 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
8089 << FirstArgumentIndex <<
")";
8091 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
8093 AttrOS.write_escaped(ReferenceFormatString->
getString());
8097 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
8108 llvm::raw_string_ostream IS(Fixit);
8116 if (LO.C23 || LO.CPlusPlus11)
8117 IS <<
"[[gnu::" <<
Attr <<
"]]";
8118 else if (LO.ObjC || LO.GNUMode)
8119 IS <<
"__attribute__((" <<
Attr <<
"))";
8133 Caller->
addAttr(FormatAttr::CreateImplicit(
8135 FormatStringIndex, FirstArgumentIndex));
8137 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
8139 FormatStringIndex, ReferenceFormatString));
8143 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
8155 unsigned format_idx,
unsigned firstDataArg,
8159 llvm::SmallBitVector &CheckedVarArgs) {
8161 if (format_idx >= Args.size()) {
8162 Diag(Loc, diag::warn_missing_format_string) <<
Range;
8166 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
8180 UncoveredArgHandler UncoveredArg;
8181 std::optional<unsigned> CallerParamIdx;
8183 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
8184 firstDataArg,
Type, CallType,
8185 true, CheckedVarArgs, UncoveredArg,
8186 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
8189 if (UncoveredArg.hasUncoveredArg()) {
8190 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
8191 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
8192 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
8195 if (CT != SLCT_NotALiteral)
8197 return CT == SLCT_CheckedLiteral;
8203 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
8209 this, Args, APK, ReferenceFormatString, format_idx,
8210 firstDataArg,
Type, *CallerParamIdx, Loc))
8220 if (Args.size() == firstDataArg) {
8221 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
8229 Diag(FormatLoc, diag::note_format_security_fixit)
8233 Diag(FormatLoc, diag::note_format_security_fixit)
8238 Diag(FormatLoc, diag::warn_format_nonliteral)
8249 const FormatStringLiteral *FExpr;
8250 const Expr *OrigFormatExpr;
8252 const unsigned FirstDataArg;
8253 const unsigned NumDataArgs;
8256 ArrayRef<const Expr *> Args;
8258 llvm::SmallBitVector CoveredArgs;
8259 bool usesPositionalArgs =
false;
8260 bool atFirstArg =
true;
8261 bool inFunctionCall;
8263 llvm::SmallBitVector &CheckedVarArgs;
8264 UncoveredArgHandler &UncoveredArg;
8267 CheckFormatHandler(Sema &s,
const FormatStringLiteral *fexpr,
8269 unsigned firstDataArg,
unsigned numDataArgs,
8271 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8273 llvm::SmallBitVector &CheckedVarArgs,
8274 UncoveredArgHandler &UncoveredArg)
8275 : S(s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
8276 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
8277 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
8278 inFunctionCall(inFunctionCall), CallType(callType),
8279 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
8280 CoveredArgs.resize(numDataArgs);
8281 CoveredArgs.reset();
8284 bool HasFormatArguments()
const {
8289 void DoneProcessing();
8291 void HandleIncompleteSpecifier(
const char *startSpecifier,
8292 unsigned specifierLen)
override;
8294 void HandleInvalidLengthModifier(
8295 const analyze_format_string::FormatSpecifier &FS,
8296 const analyze_format_string::ConversionSpecifier &CS,
8297 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID);
8299 void HandleNonStandardLengthModifier(
8300 const analyze_format_string::FormatSpecifier &FS,
8301 const char *startSpecifier,
unsigned specifierLen);
8303 void HandleNonStandardConversionSpecifier(
8304 const analyze_format_string::ConversionSpecifier &CS,
8305 const char *startSpecifier,
unsigned specifierLen);
8307 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
8309 void HandleInvalidPosition(
const char *startSpecifier,
unsigned specifierLen,
8312 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
8314 void HandleNullChar(
const char *nullCharacter)
override;
8316 template <
typename Range>
8318 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
8319 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
8320 bool IsStringLocation, Range StringRange,
8321 ArrayRef<FixItHint> Fixit = {});
8324 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
8325 const char *startSpec,
8326 unsigned specifierLen,
8327 const char *csStart,
unsigned csLen);
8329 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
8330 const char *startSpec,
8331 unsigned specifierLen);
8333 SourceRange getFormatStringRange();
8334 CharSourceRange getSpecifierRange(
const char *startSpecifier,
8335 unsigned specifierLen);
8336 SourceLocation getLocationOfByte(
const char *x);
8338 const Expr *getDataArg(
unsigned i)
const;
8340 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
8341 const analyze_format_string::ConversionSpecifier &CS,
8342 const char *startSpecifier,
unsigned specifierLen,
8345 bool CheckUnsupportedType(
const analyze_format_string::ArgType &AT,
8346 const Expr *E,
const char *startSpecifier,
8347 unsigned specifierLen);
8349 template <
typename Range>
8350 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
8351 bool IsStringLocation, Range StringRange,
8352 ArrayRef<FixItHint> Fixit = {});
8357SourceRange CheckFormatHandler::getFormatStringRange() {
8362CheckFormatHandler::getSpecifierRange(
const char *startSpecifier,
8363 unsigned specifierLen) {
8365 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
8373SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
8378void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
8379 unsigned specifierLen) {
8380 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
8381 getLocationOfByte(startSpecifier),
8383 getSpecifierRange(startSpecifier, specifierLen));
8386bool CheckFormatHandler::CheckUnsupportedType(
8388 const char *StartSpecifier,
unsigned SpecifierLen) {
8392 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_unsupported_type)
8395 getSpecifierRange(StartSpecifier, SpecifierLen));
8399void CheckFormatHandler::HandleInvalidLengthModifier(
8402 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
8414 getSpecifierRange(startSpecifier, specifierLen));
8416 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8417 << FixedLM->toString()
8422 if (DiagID == diag::warn_format_nonsensical_length)
8428 getSpecifierRange(startSpecifier, specifierLen), Hint);
8432void CheckFormatHandler::HandleNonStandardLengthModifier(
8434 const char *startSpecifier,
unsigned specifierLen) {
8443 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8447 getSpecifierRange(startSpecifier, specifierLen));
8449 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
8450 << FixedLM->toString()
8454 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8458 getSpecifierRange(startSpecifier, specifierLen));
8462void CheckFormatHandler::HandleNonStandardConversionSpecifier(
8464 const char *startSpecifier,
unsigned specifierLen) {
8470 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8474 getSpecifierRange(startSpecifier, specifierLen));
8477 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8478 << FixedCS->toString()
8481 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8485 getSpecifierRange(startSpecifier, specifierLen));
8489void CheckFormatHandler::HandlePosition(
const char *startPos,
unsigned posLen) {
8491 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8492 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8493 getLocationOfByte(startPos),
8495 getSpecifierRange(startPos, posLen));
8498void CheckFormatHandler::HandleInvalidPosition(
8499 const char *startSpecifier,
unsigned specifierLen,
8502 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8503 EmitFormatDiagnostic(
8504 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8505 getLocationOfByte(startSpecifier),
true,
8506 getSpecifierRange(startSpecifier, specifierLen));
8509void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8513 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8514 getLocationOfByte(startPos),
8516 getSpecifierRange(startPos, posLen));
8519void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8522 EmitFormatDiagnostic(
8523 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8524 getLocationOfByte(nullCharacter),
true,
8525 getFormatStringRange());
8531const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8532 return Args[FirstDataArg + i];
8535void CheckFormatHandler::DoneProcessing() {
8538 if (HasFormatArguments()) {
8541 signed notCoveredArg = CoveredArgs.find_first();
8542 if (notCoveredArg >= 0) {
8543 assert((
unsigned)notCoveredArg < NumDataArgs);
8544 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8546 UncoveredArg.setAllCovered();
8551void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8552 const Expr *ArgExpr) {
8553 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
"Invalid state");
8564 for (
auto E : DiagnosticExprs)
8567 CheckFormatHandler::EmitFormatDiagnostic(
8568 S, IsFunctionCall, DiagnosticExprs[0], PDiag, Loc,
8572bool CheckFormatHandler::HandleInvalidConversionSpecifier(
8574 unsigned specifierLen,
const char *csStart,
unsigned csLen) {
8575 bool keepGoing =
true;
8576 if (argIndex < NumDataArgs) {
8579 CoveredArgs.set(argIndex);
8594 std::string CodePointStr;
8595 if (!llvm::sys::locale::isPrint(*csStart)) {
8596 llvm::UTF32 CodePoint;
8597 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8598 const llvm::UTF8 *E =
reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8599 llvm::ConversionResult
Result =
8600 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8602 if (
Result != llvm::conversionOK) {
8603 unsigned char FirstChar = *csStart;
8604 CodePoint = (llvm::UTF32)FirstChar;
8607 llvm::raw_string_ostream
OS(CodePointStr);
8608 if (CodePoint < 256)
8609 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8610 else if (CodePoint <= 0xFFFF)
8611 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8613 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8617 EmitFormatDiagnostic(
8618 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8619 true, getSpecifierRange(startSpec, specifierLen));
8624void CheckFormatHandler::HandlePositionalNonpositionalArgs(
8625 SourceLocation Loc,
const char *startSpec,
unsigned specifierLen) {
8626 EmitFormatDiagnostic(
8627 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args), Loc,
8628 true, getSpecifierRange(startSpec, specifierLen));
8631bool CheckFormatHandler::CheckNumArgs(
8634 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8636 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8639 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8640 << (argIndex + 1) << NumDataArgs)
8641 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8642 EmitFormatDiagnostic(PDiag, getLocationOfByte(CS.
getStart()),
8644 getSpecifierRange(startSpecifier, specifierLen));
8648 UncoveredArg.setAllCovered();
8654template <
typename Range>
8657 bool IsStringLocation,
8660 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag, Loc,
8661 IsStringLocation, StringRange, FixIt);
8691template <
typename Range>
8692void CheckFormatHandler::EmitFormatDiagnostic(
8693 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8696 if (InFunctionCall) {
8701 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8705 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8706 diag::note_format_string_defined);
8708 Note << StringRange;
8717class CheckPrintfHandler :
public CheckFormatHandler {
8719 CheckPrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8721 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8723 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8725 llvm::SmallBitVector &CheckedVarArgs,
8726 UncoveredArgHandler &UncoveredArg)
8727 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8728 numDataArgs, beg, APK, Args, formatIdx,
8729 inFunctionCall, CallType, CheckedVarArgs,
8732 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8735 bool allowsObjCArg()
const {
8736 return FSType == FormatStringType::NSString ||
8737 FSType == FormatStringType::OSLog ||
8738 FSType == FormatStringType::OSTrace;
8741 bool HandleInvalidPrintfConversionSpecifier(
8742 const analyze_printf::PrintfSpecifier &FS,
const char *startSpecifier,
8743 unsigned specifierLen)
override;
8745 void handleInvalidMaskType(StringRef MaskType)
override;
8747 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8748 const char *startSpecifier,
unsigned specifierLen,
8749 const TargetInfo &
Target)
override;
8750 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8751 const char *StartSpecifier,
unsigned SpecifierLen,
8754 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
8755 unsigned k,
const char *startSpecifier,
8756 unsigned specifierLen);
8757 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8758 const analyze_printf::OptionalAmount &Amt,
8759 unsigned type,
const char *startSpecifier,
8760 unsigned specifierLen);
8761 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8762 const analyze_printf::OptionalFlag &flag,
8763 const char *startSpecifier,
unsigned specifierLen);
8764 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8765 const analyze_printf::OptionalFlag &ignoredFlag,
8766 const analyze_printf::OptionalFlag &flag,
8767 const char *startSpecifier,
unsigned specifierLen);
8768 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
const Expr *E);
8770 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8771 unsigned flagLen)
override;
8773 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8774 unsigned flagLen)
override;
8777 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8778 const char *flagsEnd,
8779 const char *conversionPosition)
override;
8784class EquatableFormatArgument {
8786 enum SpecifierSensitivity :
unsigned {
8793 enum FormatArgumentRole :
unsigned {
8801 analyze_format_string::ArgType ArgType;
8802 analyze_format_string::LengthModifier LengthMod;
8803 StringRef SpecifierLetter;
8804 CharSourceRange
Range;
8805 SourceLocation ElementLoc;
8806 FormatArgumentRole
Role : 2;
8807 SpecifierSensitivity Sensitivity : 2;
8808 unsigned Position : 14;
8809 unsigned ModifierFor : 14;
8811 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8812 bool InFunctionCall)
const;
8815 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8816 analyze_format_string::LengthModifier LengthMod,
8817 StringRef SpecifierLetter,
8818 analyze_format_string::ArgType ArgType,
8819 FormatArgumentRole
Role,
8820 SpecifierSensitivity Sensitivity,
unsigned Position,
8821 unsigned ModifierFor)
8822 : ArgType(ArgType), LengthMod(LengthMod),
8823 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8824 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8825 ModifierFor(ModifierFor) {}
8827 unsigned getPosition()
const {
return Position; }
8828 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8830 analyze_format_string::LengthModifier getLengthModifier()
const {
8833 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8835 std::string buildFormatSpecifier()
const {
8837 llvm::raw_string_ostream(result)
8838 << getLengthModifier().
toString() << SpecifierLetter;
8842 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8843 const Expr *FmtExpr,
bool InFunctionCall)
const;
8847class DecomposePrintfHandler :
public CheckPrintfHandler {
8848 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8851 DecomposePrintfHandler(Sema &s,
const FormatStringLiteral *fexpr,
8852 const Expr *origFormatExpr,
8854 unsigned numDataArgs,
bool isObjC,
const char *beg,
8856 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8858 llvm::SmallBitVector &CheckedVarArgs,
8859 UncoveredArgHandler &UncoveredArg,
8860 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8861 : CheckPrintfHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
8862 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8863 inFunctionCall, CallType, CheckedVarArgs,
8865 Specs(Specs), HadError(
false) {}
8869 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8871 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8873 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8874 const char *startSpecifier,
8875 unsigned specifierLen,
8876 const TargetInfo &
Target)
override;
8881bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8883 unsigned specifierLen) {
8887 return HandleInvalidConversionSpecifier(
8892void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8893 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8901 return T->isRecordType() ||
T->isComplexType();
8904bool CheckPrintfHandler::HandleAmount(
8906 const char *startSpecifier,
unsigned specifierLen) {
8908 if (HasFormatArguments()) {
8910 if (argIndex >= NumDataArgs) {
8911 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8915 getSpecifierRange(startSpecifier, specifierLen));
8925 CoveredArgs.set(argIndex);
8926 const Expr *Arg = getDataArg(argIndex);
8937 ? diag::err_printf_asterisk_wrong_type
8938 : diag::warn_printf_asterisk_wrong_type;
8939 EmitFormatDiagnostic(S.
PDiag(DiagID)
8944 getSpecifierRange(startSpecifier, specifierLen));
8954void CheckPrintfHandler::HandleInvalidAmount(
8957 const char *startSpecifier,
unsigned specifierLen) {
8967 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8971 getSpecifierRange(startSpecifier, specifierLen), fixit);
8976 const char *startSpecifier,
8977 unsigned specifierLen) {
8981 EmitFormatDiagnostic(
8982 S.
PDiag(diag::warn_printf_nonsensical_flag)
8986 getSpecifierRange(startSpecifier, specifierLen),
8990void CheckPrintfHandler::HandleIgnoredFlag(
8994 unsigned specifierLen) {
8996 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
9000 getSpecifierRange(startSpecifier, specifierLen),
9002 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
9005void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
9008 EmitFormatDiagnostic(
9009 S.
PDiag(diag::warn_printf_empty_objc_flag), getLocationOfByte(startFlag),
9010 true, getSpecifierRange(startFlag, flagLen));
9013void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
9016 auto Range = getSpecifierRange(startFlag, flagLen);
9017 StringRef flag(startFlag, flagLen);
9018 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
9019 getLocationOfByte(startFlag),
9024void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
9025 const char *flagsStart,
const char *flagsEnd,
9026 const char *conversionPosition) {
9028 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
9029 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
9030 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
9031 getLocationOfByte(conversionPosition),
9037 const Expr *FmtExpr,
9038 bool InFunctionCall)
const {
9039 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
9040 ElementLoc,
true, Range);
9043bool EquatableFormatArgument::VerifyCompatible(
9044 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
9045 bool InFunctionCall)
const {
9050 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
9051 FmtExpr, InFunctionCall);
9052 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
9056 if (
Role != FAR_Data) {
9057 if (ModifierFor !=
Other.ModifierFor) {
9060 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
9061 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
9062 FmtExpr, InFunctionCall);
9063 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
9069 bool HadError =
false;
9070 if (Sensitivity !=
Other.Sensitivity) {
9073 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
9074 << Sensitivity <<
Other.Sensitivity,
9075 FmtExpr, InFunctionCall);
9076 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9077 << 0 <<
Other.Range;
9080 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
9084 case MK::MatchPromotion:
9088 case MK::NoMatchTypeConfusion:
9089 case MK::NoMatchPromotionTypeConfusion:
9091 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
9092 << buildFormatSpecifier()
9093 <<
Other.buildFormatSpecifier(),
9094 FmtExpr, InFunctionCall);
9095 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9096 << 0 <<
Other.Range;
9099 case MK::NoMatchPedantic:
9101 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
9102 << buildFormatSpecifier()
9103 <<
Other.buildFormatSpecifier(),
9104 FmtExpr, InFunctionCall);
9105 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9106 << 0 <<
Other.Range;
9109 case MK::NoMatchSignedness:
9111 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
9112 << buildFormatSpecifier()
9113 <<
Other.buildFormatSpecifier(),
9114 FmtExpr, InFunctionCall);
9115 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
9116 << 0 <<
Other.Range;
9122bool DecomposePrintfHandler::GetSpecifiers(
9123 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
9126 StringRef
Data = FSL->getString();
9127 const char *Str =
Data.data();
9128 llvm::SmallBitVector BV;
9129 UncoveredArgHandler UA;
9130 const Expr *PrintfArgs[] = {FSL->getFormatString()};
9131 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
9143 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
9144 const EquatableFormatArgument &B) {
9145 return A.getPosition() < B.getPosition();
9150bool DecomposePrintfHandler::HandlePrintfSpecifier(
9153 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
9168 const unsigned Unset = ~0;
9169 unsigned FieldWidthIndex = Unset;
9170 unsigned PrecisionIndex = Unset;
9174 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
9175 FieldWidthIndex = Specs.size();
9177 getSpecifierRange(startSpecifier, specifierLen),
9178 getLocationOfByte(FieldWidth.getStart()),
9180 FieldWidth.getArgType(S.
Context),
9181 EquatableFormatArgument::FAR_FieldWidth,
9182 EquatableFormatArgument::SS_None,
9183 FieldWidth.usesPositionalArg() ? FieldWidth.getPositionalArgIndex() - 1
9189 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
9190 PrecisionIndex = Specs.size();
9192 getSpecifierRange(startSpecifier, specifierLen),
9193 getLocationOfByte(Precision.getStart()),
9195 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
9196 EquatableFormatArgument::SS_None,
9197 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
9203 unsigned SpecIndex =
9205 if (FieldWidthIndex != Unset)
9206 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
9207 if (PrecisionIndex != Unset)
9208 Specs[PrecisionIndex].setModifierFor(SpecIndex);
9210 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
9212 Sensitivity = EquatableFormatArgument::SS_Private;
9214 Sensitivity = EquatableFormatArgument::SS_Public;
9216 Sensitivity = EquatableFormatArgument::SS_Sensitive;
9218 Sensitivity = EquatableFormatArgument::SS_None;
9221 getSpecifierRange(startSpecifier, specifierLen),
9224 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
9229 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
9234 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
9235 SpecIndex + 1, SpecIndex);
9243template<
typename MemberKind>
9254 R.suppressDiagnostics();
9261 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
9276 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9278 if ((*MI)->getMinRequiredArguments() == 0)
9286bool CheckPrintfHandler::checkForCStrMembers(
9293 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
9296 if (
Method->getMinRequiredArguments() == 0 &&
9309bool CheckPrintfHandler::HandlePrintfSpecifier(
9322 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
9323 startSpecifier, specifierLen);
9335 if (!HandleAmount(FS.
getPrecision(), 1, startSpecifier,
9340 if (!CS.consumesDataArgument()) {
9348 if (argIndex < NumDataArgs) {
9352 CoveredArgs.set(argIndex);
9359 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
9362 if (HasFormatArguments()) {
9364 CoveredArgs.set(argIndex + 1);
9367 const Expr *Ex = getDataArg(argIndex);
9371 : ArgType::CPointerTy;
9373 EmitFormatDiagnostic(
9374 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9378 getSpecifierRange(startSpecifier, specifierLen));
9381 Ex = getDataArg(argIndex + 1);
9384 EmitFormatDiagnostic(
9385 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9389 getSpecifierRange(startSpecifier, specifierLen));
9396 if (!allowsObjCArg() && CS.isObjCArg()) {
9397 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9404 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9411 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
9412 getLocationOfByte(CS.getStart()),
9414 getSpecifierRange(startSpecifier, specifierLen));
9424 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
9431 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9435 getSpecifierRange(startSpecifier, specifierLen));
9438 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
9442 getSpecifierRange(startSpecifier, specifierLen));
9446 const llvm::Triple &Triple =
Target.getTriple();
9448 (Triple.isAndroid() || Triple.isOSFuchsia())) {
9449 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
9450 getLocationOfByte(CS.getStart()),
9452 getSpecifierRange(startSpecifier, specifierLen));
9458 startSpecifier, specifierLen);
9464 startSpecifier, specifierLen);
9470 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9471 getLocationOfByte(startSpecifier),
9473 getSpecifierRange(startSpecifier, specifierLen));
9482 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9484 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9493 startSpecifier, specifierLen);
9496 startSpecifier, specifierLen);
9501 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9502 diag::warn_format_nonsensical_length);
9504 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9506 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9507 diag::warn_format_non_standard_conversion_spec);
9510 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9513 if (!HasFormatArguments())
9516 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9519 const Expr *Arg = getDataArg(argIndex);
9523 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9535 case Stmt::ArraySubscriptExprClass:
9536 case Stmt::CallExprClass:
9537 case Stmt::CharacterLiteralClass:
9538 case Stmt::CXXBoolLiteralExprClass:
9539 case Stmt::DeclRefExprClass:
9540 case Stmt::FloatingLiteralClass:
9541 case Stmt::IntegerLiteralClass:
9542 case Stmt::MemberExprClass:
9543 case Stmt::ObjCArrayLiteralClass:
9544 case Stmt::ObjCBoolLiteralExprClass:
9545 case Stmt::ObjCBoxedExprClass:
9546 case Stmt::ObjCDictionaryLiteralClass:
9547 case Stmt::ObjCEncodeExprClass:
9548 case Stmt::ObjCIvarRefExprClass:
9549 case Stmt::ObjCMessageExprClass:
9550 case Stmt::ObjCPropertyRefExprClass:
9551 case Stmt::ObjCStringLiteralClass:
9552 case Stmt::ObjCSubscriptRefExprClass:
9553 case Stmt::ParenExprClass:
9554 case Stmt::StringLiteralClass:
9555 case Stmt::UnaryOperatorClass:
9562static std::pair<QualType, StringRef>
9568 StringRef Name = UserTy->getDecl()->getName();
9569 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9570 .Case(
"CFIndex", Context.getNSIntegerType())
9571 .Case(
"NSInteger", Context.getNSIntegerType())
9572 .Case(
"NSUInteger", Context.getNSUIntegerType())
9573 .Case(
"SInt32", Context.IntTy)
9574 .Case(
"UInt32", Context.UnsignedIntTy)
9578 return std::make_pair(CastTy, Name);
9580 TyTy = UserTy->desugar();
9584 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9594 StringRef TrueName, FalseName;
9597 Context, CO->getTrueExpr()->getType(), CO->getTrueExpr());
9599 Context, CO->getFalseExpr()->getType(), CO->getFalseExpr());
9601 if (TrueTy == FalseTy)
9602 return std::make_pair(TrueTy, TrueName);
9603 else if (TrueTy.
isNull())
9604 return std::make_pair(FalseTy, FalseName);
9605 else if (FalseTy.
isNull())
9606 return std::make_pair(TrueTy, TrueName);
9609 return std::make_pair(
QualType(), StringRef());
9628 From = VecTy->getElementType();
9630 To = VecTy->getElementType();
9641 diag::warn_format_conversion_argument_type_mismatch_signedness,
9645 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9652bool CheckPrintfHandler::checkFormatExpr(
9654 unsigned SpecifierLen,
const Expr *E) {
9665 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9669 if (
const OverflowBehaviorType *OBT =
9670 dyn_cast<OverflowBehaviorType>(
ExprTy.getCanonicalType()))
9671 ExprTy = OBT->getUnderlyingType();
9676 if (
ExprTy->canDecayToPointerType())
9685 getSpecifierRange(StartSpecifier, SpecifierLen);
9687 llvm::raw_svector_ostream os(FSString);
9689 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9698 ExprTy->isObjCObjectPointerType()) {
9700 getSpecifierRange(StartSpecifier, SpecifierLen);
9701 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9706 if (CheckUnsupportedType(AT, E, StartSpecifier, SpecifierLen))
9714 if (
Match == ArgType::Match)
9718 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9727 E = ICE->getSubExpr();
9737 if (OrigMatch == ArgType::NoMatchSignedness &&
9738 ImplicitMatch != ArgType::NoMatchSignedness)
9745 if (ImplicitMatch == ArgType::Match)
9763 if (
Match == ArgType::MatchPromotion)
9767 if (
Match == ArgType::MatchPromotion) {
9771 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9772 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9776 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9777 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9778 Match = ImplicitMatch;
9779 assert(
Match != ArgType::MatchPromotion);
9782 bool IsEnum =
false;
9783 bool IsScopedEnum =
false;
9785 if (
const auto *ED =
ExprTy->getAsEnumDecl()) {
9786 IntendedTy = ED->getIntegerType();
9787 if (!ED->isScoped()) {
9793 IsScopedEnum =
true;
9800 if (isObjCContext() &&
9802 if (
ExprTy->isIntegralOrUnscopedEnumerationType() &&
9811 const llvm::APInt &
V = IL->getValue();
9821 if (TD->getUnderlyingType() == IntendedTy)
9831 bool ShouldNotPrintDirectly =
false;
9832 StringRef CastTyName;
9835 std::tie(CastTy, CastTyName) =
9841 if (!IsScopedEnum &&
9842 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9846 IntendedTy = CastTy;
9847 ShouldNotPrintDirectly =
true;
9852 PrintfSpecifier fixedFS = FS;
9859 llvm::raw_svector_ostream os(buf);
9862 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9864 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9870 llvm_unreachable(
"expected non-matching");
9872 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9875 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9878 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9881 Diag = diag::warn_format_conversion_argument_type_mismatch;
9902 llvm::raw_svector_ostream CastFix(CastBuf);
9903 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9905 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9911 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9916 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9938 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9944 Name = TypedefTy->getDecl()->getName();
9948 ? diag::warn_format_argument_needs_cast_pedantic
9949 : diag::warn_format_argument_needs_cast;
9950 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9961 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9962 : diag::warn_format_conversion_argument_type_mismatch;
9964 EmitFormatDiagnostic(
9972 getSpecifierRange(StartSpecifier, SpecifierLen);
9976 bool EmitTypeMismatch =
false;
9980 bool EmitOSLogError =
false;
9989 llvm_unreachable(
"expected non-matching");
9991 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9994 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9997 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
10001 Diag = diag::warn_format_conversion_argument_type_mismatch;
10005 if (!EmitOSLogError)
10006 EmitFormatDiagnostic(
10015 EmitTypeMismatch =
true;
10019 EmitOSLogError =
true;
10021 EmitFormatDiagnostic(
10022 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
10023 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
10027 checkForCStrMembers(AT, E);
10033 EmitTypeMismatch =
true;
10034 else if (
ExprTy->isObjCObjectType())
10035 EmitFormatDiagnostic(
10036 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
10037 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
10050 if (EmitOSLogError)
10051 EmitFormatDiagnostic(
10052 S.
PDiag(diag::err_format_conversion_argument_type_mismatch)
10057 if (EmitTypeMismatch) {
10063 EmitFormatDiagnostic(
10064 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
10070 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
10071 "format string specifier index out of range");
10072 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
10082class CheckScanfHandler :
public CheckFormatHandler {
10084 CheckScanfHandler(Sema &s,
const FormatStringLiteral *fexpr,
10086 unsigned firstDataArg,
unsigned numDataArgs,
10088 ArrayRef<const Expr *> Args,
unsigned formatIdx,
10090 llvm::SmallBitVector &CheckedVarArgs,
10091 UncoveredArgHandler &UncoveredArg)
10092 : CheckFormatHandler(s, fexpr, origFormatExpr,
type, firstDataArg,
10093 numDataArgs, beg, APK, Args, formatIdx,
10094 inFunctionCall, CallType, CheckedVarArgs,
10097 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
10098 const char *startSpecifier,
10099 unsigned specifierLen)
override;
10102 HandleInvalidScanfConversionSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
10103 const char *startSpecifier,
10104 unsigned specifierLen)
override;
10106 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
10111void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
10113 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
10114 getLocationOfByte(end),
true,
10115 getSpecifierRange(start, end - start));
10118bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
10120 unsigned specifierLen) {
10124 return HandleInvalidConversionSpecifier(
10129bool CheckScanfHandler::HandleScanfSpecifier(
10131 unsigned specifierLen) {
10141 atFirstArg =
false;
10144 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
10145 startSpecifier, specifierLen);
10156 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
10157 getLocationOfByte(Amt.
getStart()),
10171 if (argIndex < NumDataArgs) {
10175 CoveredArgs.set(argIndex);
10181 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10182 diag::warn_format_nonsensical_length);
10184 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
10186 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
10187 diag::warn_format_non_standard_conversion_spec);
10190 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
10193 if (!HasFormatArguments())
10196 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
10200 const Expr *Ex = getDataArg(argIndex);
10210 if (CheckUnsupportedType(AT, Ex, startSpecifier, specifierLen))
10221 ScanfSpecifier fixedFS = FS;
10226 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
10228 ? diag::warn_format_conversion_argument_type_mismatch_signedness
10229 : diag::warn_format_conversion_argument_type_mismatch;
10234 llvm::raw_svector_ostream os(buf);
10237 EmitFormatDiagnostic(
10242 getSpecifierRange(startSpecifier, specifierLen),
10244 getSpecifierRange(startSpecifier, specifierLen), os.str()));
10251 getSpecifierRange(startSpecifier, specifierLen));
10261 const Expr *FmtExpr,
bool InFunctionCall) {
10262 bool HadError =
false;
10263 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
10264 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
10265 while (FmtIter < FmtEnd && RefIter < RefEnd) {
10277 for (; FmtIter < FmtEnd; ++FmtIter) {
10281 if (FmtIter->getPosition() < RefIter->getPosition())
10285 if (FmtIter->getPosition() > RefIter->getPosition())
10289 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
10293 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
10294 return Arg.getPosition() != RefIter->getPosition();
10298 if (FmtIter < FmtEnd) {
10299 CheckFormatHandler::EmitFormatDiagnostic(
10300 S, InFunctionCall, FmtExpr,
10301 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
10302 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
10303 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
10304 }
else if (RefIter < RefEnd) {
10305 CheckFormatHandler::EmitFormatDiagnostic(
10306 S, InFunctionCall, FmtExpr,
10307 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
10310 << 1 << RefIter->getSourceRange();
10316 Sema &S,
const FormatStringLiteral *FExpr,
10321 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
10322 bool IgnoreStringsWithoutSpecifiers) {
10324 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
10325 CheckFormatHandler::EmitFormatDiagnostic(
10326 S, inFunctionCall, Args[format_idx],
10327 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
10333 StringRef StrRef = FExpr->getString();
10334 const char *Str = StrRef.data();
10338 assert(
T &&
"String literal not of constant array type!");
10339 size_t TypeSize =
T->getZExtSize();
10340 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10341 const unsigned numDataArgs = Args.size() - firstDataArg;
10343 if (IgnoreStringsWithoutSpecifiers &&
10350 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
10351 CheckFormatHandler::EmitFormatDiagnostic(
10352 S, inFunctionCall, Args[format_idx],
10353 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
10354 FExpr->getBeginLoc(),
10360 if (StrLen == 0 && numDataArgs > 0) {
10361 CheckFormatHandler::EmitFormatDiagnostic(
10362 S, inFunctionCall, Args[format_idx],
10363 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
10374 if (ReferenceFormatString ==
nullptr) {
10375 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10376 numDataArgs, IsObjC, Str, APK, Args, format_idx,
10377 inFunctionCall, CallType, CheckedVarArgs,
10384 H.DoneProcessing();
10387 Type, ReferenceFormatString, FExpr->getFormatString(),
10388 inFunctionCall ?
nullptr : Args[format_idx]);
10391 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
10392 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
10393 CallType, CheckedVarArgs, UncoveredArg);
10397 H.DoneProcessing();
10413 FormatStringLiteral RefLit = AuthoritativeFormatString;
10414 FormatStringLiteral TestLit = TestedFormatString;
10416 bool DiagAtStringLiteral;
10417 if (FunctionCallArg) {
10418 Arg = FunctionCallArg;
10419 DiagAtStringLiteral =
false;
10421 Arg = TestedFormatString;
10422 DiagAtStringLiteral =
true;
10424 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
10425 AuthoritativeFormatString,
Type,
10426 IsObjC,
true, RefArgs) &&
10427 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
10428 DiagAtStringLiteral, FmtArgs)) {
10430 TestedFormatString, FmtArgs, Arg,
10431 DiagAtStringLiteral);
10444 FormatStringLiteral RefLit = Str;
10448 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
10457 bool HadError =
false;
10458 auto Iter = Args.begin();
10459 auto End = Args.end();
10460 while (Iter != End) {
10461 const auto &FirstInGroup = *Iter;
10463 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
10465 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10474 const char *Str = StrRef.data();
10477 assert(
T &&
"String literal not of constant array type!");
10478 size_t TypeSize =
T->getZExtSize();
10479 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10489 switch (AbsFunction) {
10493 case Builtin::BI__builtin_abs:
10494 return Builtin::BI__builtin_labs;
10495 case Builtin::BI__builtin_labs:
10496 return Builtin::BI__builtin_llabs;
10497 case Builtin::BI__builtin_llabs:
10500 case Builtin::BI__builtin_fabsf:
10501 return Builtin::BI__builtin_fabs;
10502 case Builtin::BI__builtin_fabs:
10503 return Builtin::BI__builtin_fabsl;
10504 case Builtin::BI__builtin_fabsl:
10507 case Builtin::BI__builtin_cabsf:
10508 return Builtin::BI__builtin_cabs;
10509 case Builtin::BI__builtin_cabs:
10510 return Builtin::BI__builtin_cabsl;
10511 case Builtin::BI__builtin_cabsl:
10514 case Builtin::BIabs:
10515 return Builtin::BIlabs;
10516 case Builtin::BIlabs:
10517 return Builtin::BIllabs;
10518 case Builtin::BIllabs:
10521 case Builtin::BIfabsf:
10522 return Builtin::BIfabs;
10523 case Builtin::BIfabs:
10524 return Builtin::BIfabsl;
10525 case Builtin::BIfabsl:
10528 case Builtin::BIcabsf:
10529 return Builtin::BIcabs;
10530 case Builtin::BIcabs:
10531 return Builtin::BIcabsl;
10532 case Builtin::BIcabsl:
10539 unsigned AbsType) {
10561 unsigned AbsFunctionKind) {
10562 unsigned BestKind = 0;
10563 uint64_t ArgSize = Context.getTypeSize(ArgType);
10564 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10567 if (Context.getTypeSize(ParamType) >= ArgSize) {
10570 else if (Context.hasSameType(ParamType, ArgType)) {
10586 if (
T->isIntegralOrEnumerationType())
10588 if (
T->isRealFloatingType())
10590 if (
T->isAnyComplexType())
10593 llvm_unreachable(
"Type not integer, floating, or complex");
10600 switch (ValueKind) {
10605 case Builtin::BI__builtin_fabsf:
10606 case Builtin::BI__builtin_fabs:
10607 case Builtin::BI__builtin_fabsl:
10608 case Builtin::BI__builtin_cabsf:
10609 case Builtin::BI__builtin_cabs:
10610 case Builtin::BI__builtin_cabsl:
10611 return Builtin::BI__builtin_abs;
10612 case Builtin::BIfabsf:
10613 case Builtin::BIfabs:
10614 case Builtin::BIfabsl:
10615 case Builtin::BIcabsf:
10616 case Builtin::BIcabs:
10617 case Builtin::BIcabsl:
10618 return Builtin::BIabs;
10624 case Builtin::BI__builtin_abs:
10625 case Builtin::BI__builtin_labs:
10626 case Builtin::BI__builtin_llabs:
10627 case Builtin::BI__builtin_cabsf:
10628 case Builtin::BI__builtin_cabs:
10629 case Builtin::BI__builtin_cabsl:
10630 return Builtin::BI__builtin_fabsf;
10631 case Builtin::BIabs:
10632 case Builtin::BIlabs:
10633 case Builtin::BIllabs:
10634 case Builtin::BIcabsf:
10635 case Builtin::BIcabs:
10636 case Builtin::BIcabsl:
10637 return Builtin::BIfabsf;
10643 case Builtin::BI__builtin_abs:
10644 case Builtin::BI__builtin_labs:
10645 case Builtin::BI__builtin_llabs:
10646 case Builtin::BI__builtin_fabsf:
10647 case Builtin::BI__builtin_fabs:
10648 case Builtin::BI__builtin_fabsl:
10649 return Builtin::BI__builtin_cabsf;
10650 case Builtin::BIabs:
10651 case Builtin::BIlabs:
10652 case Builtin::BIllabs:
10653 case Builtin::BIfabsf:
10654 case Builtin::BIfabs:
10655 case Builtin::BIfabsl:
10656 return Builtin::BIcabsf;
10659 llvm_unreachable(
"Unable to convert function");
10670 case Builtin::BI__builtin_abs:
10671 case Builtin::BI__builtin_fabs:
10672 case Builtin::BI__builtin_fabsf:
10673 case Builtin::BI__builtin_fabsl:
10674 case Builtin::BI__builtin_labs:
10675 case Builtin::BI__builtin_llabs:
10676 case Builtin::BI__builtin_cabs:
10677 case Builtin::BI__builtin_cabsf:
10678 case Builtin::BI__builtin_cabsl:
10679 case Builtin::BIabs:
10680 case Builtin::BIlabs:
10681 case Builtin::BIllabs:
10682 case Builtin::BIfabs:
10683 case Builtin::BIfabsf:
10684 case Builtin::BIfabsl:
10685 case Builtin::BIcabs:
10686 case Builtin::BIcabsf:
10687 case Builtin::BIcabsl:
10690 llvm_unreachable(
"Unknown Builtin type");
10696 unsigned AbsKind,
QualType ArgType) {
10697 bool EmitHeaderHint =
true;
10698 const char *HeaderName =
nullptr;
10699 std::string FunctionName;
10700 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10701 FunctionName =
"std::abs";
10702 if (ArgType->isIntegralOrEnumerationType()) {
10703 HeaderName =
"cstdlib";
10704 }
else if (ArgType->isRealFloatingType()) {
10705 HeaderName =
"cmath";
10707 llvm_unreachable(
"Invalid Type");
10713 R.suppressDiagnostics();
10716 for (
const auto *I : R) {
10719 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10721 FDecl = dyn_cast<FunctionDecl>(I);
10736 EmitHeaderHint =
false;
10748 R.suppressDiagnostics();
10751 if (R.isSingleResult()) {
10752 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10754 EmitHeaderHint =
false;
10758 }
else if (!R.empty()) {
10764 S.
Diag(Loc, diag::note_replace_abs_function)
10770 if (!EmitHeaderHint)
10773 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10777template <std::
size_t StrLen>
10779 const char (&Str)[StrLen]) {
10792 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10793 return llvm::is_contained(names, calleeName);
10798 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10799 "__builtin_nanf16",
"__builtin_nanf128"});
10801 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10802 "__builtin_inff16",
"__builtin_inff128"});
10804 llvm_unreachable(
"unknown MathCheck");
10808 if (FDecl->
getName() !=
"infinity")
10811 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10813 if (RDecl->
getName() !=
"numeric_limits")
10830 if (FPO.getNoHonorNaNs() &&
10833 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10834 << 1 << 0 <<
Call->getSourceRange();
10838 if (FPO.getNoHonorInfs() &&
10842 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10843 << 0 << 0 <<
Call->getSourceRange();
10847void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10849 if (
Call->getNumArgs() != 1)
10854 if (AbsKind == 0 && !IsStdAbs)
10857 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10858 QualType ParamType =
Call->getArg(0)->getType();
10863 std::string FunctionName =
10864 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10865 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10866 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10901 if (ArgValueKind == ParamValueKind) {
10902 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10906 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10907 << FDecl << ArgType << ParamType;
10909 if (NewAbsKind == 0)
10913 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10922 if (NewAbsKind == 0)
10925 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10926 << FDecl << ParamValueKind << ArgValueKind;
10929 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10935 if (!
Call || !FDecl)
return;
10939 if (
Call->getExprLoc().isMacroID())
return;
10942 if (
Call->getNumArgs() != 2)
return;
10945 if (!ArgList)
return;
10946 if (ArgList->size() != 1)
return;
10949 const auto& TA = ArgList->
get(0);
10951 QualType ArgType = TA.getAsType();
10955 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10956 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10957 if (!MTE)
return false;
10958 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10959 if (!
Num)
return false;
10960 if (
Num->getValue() != 0)
return false;
10964 const Expr *FirstArg =
Call->getArg(0);
10965 const Expr *SecondArg =
Call->getArg(1);
10966 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10967 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10970 if (IsFirstArgZero == IsSecondArgZero)
return;
10975 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10977 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10978 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10981 SourceRange RemovalRange;
10982 if (IsFirstArgZero) {
10983 RemovalRange = SourceRange(FirstRange.
getBegin(),
10990 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
11005 const auto *Size = dyn_cast<BinaryOperator>(E);
11010 if (!Size->isComparisonOp() && !Size->isLogicalOp())
11014 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
11015 << SizeRange << FnName;
11016 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
11021 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
11032 bool &IsContained) {
11034 const Type *Ty =
T->getBaseElementTypeUnsafe();
11035 IsContained =
false;
11048 for (
auto *FD : RD->
fields()) {
11052 IsContained =
true;
11053 return ContainedRD;
11061 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
11062 if (Unary->getKind() == UETT_SizeOf)
11071 if (!
SizeOf->isArgumentType())
11072 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
11079 return SizeOf->getTypeOfArgument();
11085struct SearchNonTrivialToInitializeField
11088 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
11090 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
11093 SourceLocation SL) {
11094 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
11095 asDerived().visitArray(PDIK, AT, SL);
11099 Super::visitWithKind(PDIK, FT, SL);
11102 void visitARCStrong(QualType FT, SourceLocation SL) {
11105 void visitARCWeak(QualType FT, SourceLocation SL) {
11108 void visitStruct(QualType FT, SourceLocation SL) {
11113 const ArrayType *AT, SourceLocation SL) {
11114 visit(getContext().getBaseElementType(AT), SL);
11116 void visitTrivial(QualType FT, SourceLocation SL) {}
11118 static void diag(QualType RT,
const Expr *E, Sema &S) {
11119 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
11128struct SearchNonTrivialToCopyField
11130 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
11132 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
11135 SourceLocation SL) {
11136 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
11137 asDerived().visitArray(PCK, AT, SL);
11141 Super::visitWithKind(PCK, FT, SL);
11144 void visitARCStrong(QualType FT, SourceLocation SL) {
11147 void visitARCWeak(QualType FT, SourceLocation SL) {
11150 void visitPtrAuth(QualType FT, SourceLocation SL) {
11153 void visitStruct(QualType FT, SourceLocation SL) {
11158 SourceLocation SL) {
11159 visit(getContext().getBaseElementType(AT), SL);
11162 SourceLocation SL) {}
11163 void visitTrivial(QualType FT, SourceLocation SL) {}
11164 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
11166 static void diag(QualType RT,
const Expr *E, Sema &S) {
11167 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
11182 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
11183 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
11216 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
11219 const Expr *SizeArg =
11220 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
11222 auto isLiteralZero = [](
const Expr *E) {
11232 if (isLiteralZero(SizeArg) &&
11239 if (BId == Builtin::BIbzero ||
11242 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
11243 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
11244 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
11245 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
11246 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
11254 if (BId == Builtin::BImemset &&
11258 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
11259 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
11264void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
11271 unsigned ExpectedNumArgs =
11272 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
11273 if (
Call->getNumArgs() < ExpectedNumArgs)
11276 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
11277 BId == Builtin::BIstrndup ? 1 : 2);
11279 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
11283 Call->getBeginLoc(),
Call->getRParenLoc()))
11295 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
11296 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
11299 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
11303 QualType DestTy = Dest->
getType();
11304 QualType PointeeTy;
11305 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
11317 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
11323 if (SizeOfArgTy != QualType()) {
11325 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
11327 PDiag(diag::warn_sizeof_pointer_type_memaccess)
11328 << FnName << SizeOfArgTy << ArgIdx
11335 PointeeTy = DestTy;
11338 if (PointeeTy == QualType())
11343 if (
const CXXRecordDecl *ContainedRD =
11346 unsigned OperationType = 0;
11347 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
11350 if (ArgIdx != 0 || IsCmp) {
11351 if (BId == Builtin::BImemcpy)
11353 else if(BId == Builtin::BImemmove)
11360 PDiag(diag::warn_dyn_class_memaccess)
11361 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
11362 << IsContained << ContainedRD << OperationType
11363 <<
Call->getCallee()->getSourceRange());
11365 BId != Builtin::BImemset)
11368 PDiag(diag::warn_arc_object_memaccess)
11369 << ArgIdx << FnName << PointeeTy
11370 <<
Call->getCallee()->getSourceRange());
11377 bool NonTriviallyCopyableCXXRecord =
11381 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11384 PDiag(diag::warn_cstruct_memaccess)
11385 << ArgIdx << FnName << PointeeTy << 0);
11386 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
11387 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
11388 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11392 PDiag(diag::warn_cxxstruct_memaccess)
11393 << FnName << PointeeTy);
11394 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11397 PDiag(diag::warn_cstruct_memaccess)
11398 << ArgIdx << FnName << PointeeTy << 1);
11399 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
11400 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
11401 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
11405 PDiag(diag::warn_cxxstruct_memaccess)
11406 << FnName << PointeeTy);
11415 PDiag(diag::note_bad_memaccess_silence)
11421bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
11423 llvm::FoldingSetNodeID SizeOfArgID;
11429 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
11432 QualType DestTy = Dest->
getType();
11433 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
11439 if (SizeOfArgID == llvm::FoldingSetNodeID())
11442 llvm::FoldingSetNodeID DestID;
11444 if (DestID == SizeOfArgID) {
11447 unsigned ActionIdx = 0;
11448 StringRef ReadableName = FnName->
getName();
11450 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
11451 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
11460 SourceLocation SL = SizeOfArg->
getExprLoc();
11475 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11476 << ReadableName << PointeeTy << DestTy << DSR
11479 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11480 << ActionIdx << SSR);
11516 if (CAT->getZExtSize() <= 1)
11524void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11528 unsigned NumArgs =
Call->getNumArgs();
11529 if ((NumArgs != 3) && (NumArgs != 4))
11534 const Expr *CompareWithSrc =
nullptr;
11537 Call->getBeginLoc(),
Call->getRParenLoc()))
11542 CompareWithSrc = Ex;
11545 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11546 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11547 SizeCall->getNumArgs() == 1)
11552 if (!CompareWithSrc)
11559 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11563 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11564 if (!CompareWithSrcDRE ||
11568 const Expr *OriginalSizeArg =
Call->getArg(2);
11569 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11576 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11580 SmallString<128> sizeString;
11581 llvm::raw_svector_ostream
OS(sizeString);
11586 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11593 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11594 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11595 return D1->getDecl() == D2->getDecl();
11600 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11609void Sema::CheckStrncatArguments(
const CallExpr *CE,
11624 unsigned PatternType = 0;
11632 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11633 if (BE->getOpcode() == BO_Sub) {
11634 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11635 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11646 if (PatternType == 0)
11662 QualType DstTy = DstArg->
getType();
11665 if (!isKnownSizeArray) {
11666 if (PatternType == 1)
11667 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11669 Diag(SL, diag::warn_strncat_src_size) << SR;
11673 if (PatternType == 1)
11674 Diag(SL, diag::warn_strncat_large_size) << SR;
11676 Diag(SL, diag::warn_strncat_src_size) << SR;
11678 SmallString<128> sizeString;
11679 llvm::raw_svector_ostream
OS(sizeString);
11687 Diag(SL, diag::note_strncat_wrong_size)
11692void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11701void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11703 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11704 const Decl *D = Lvalue->getDecl();
11705 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11706 if (!DD->getType()->isReferenceType())
11707 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11711 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11712 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11713 Lvalue->getMemberDecl());
11716void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11718 const auto *Lambda = dyn_cast<LambdaExpr>(
11723 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11724 << CalleeName << 2 ;
11727void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11729 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11730 if (Var ==
nullptr)
11734 << CalleeName << 0 << Var;
11737void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11740 llvm::raw_svector_ostream
OS(SizeString);
11743 if (Kind == clang::CK_BitCast &&
11744 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11746 if (Kind == clang::CK_IntegralToPointer &&
11748 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11751 switch (
Cast->getCastKind()) {
11752 case clang::CK_BitCast:
11753 case clang::CK_IntegralToPointer:
11754 case clang::CK_FunctionToPointerDecay:
11763 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11764 << CalleeName << 0 <<
OS.str();
11768void Sema::CheckFreeArguments(
const CallExpr *E) {
11769 const std::string CalleeName =
11774 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11776 case UnaryOperator::Opcode::UO_AddrOf:
11777 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11778 case UnaryOperator::Opcode::UO_Plus:
11779 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11784 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11786 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11788 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11789 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11790 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11796 << CalleeName << 1 ;
11801 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11802 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11806Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11815 Diag(ReturnLoc, diag::warn_null_ret)
11825 if (Op == OO_New || Op == OO_Array_New) {
11826 const FunctionProtoType *Proto
11830 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11836 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11841 if (
Context.getTargetInfo().getTriple().isPPC64())
11853 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11854 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11855 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11856 return FPLiteral && FPCast;
11859 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11865 llvm::APFloat TargetC = FPLiteral->
getValue();
11866 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11867 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11871 Diag(Loc, diag::warn_float_compare_literal)
11872 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11885 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11886 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11887 if (DRL->getDecl() == DRR->getDecl())
11895 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11896 if (FLL->isExact())
11898 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11899 if (FLR->isExact())
11903 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11904 CL &&
CL->getBuiltinCallee())
11907 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11908 CR && CR->getBuiltinCallee())
11912 Diag(Loc, diag::warn_floatingpoint_eq)
11933 IntRange(
unsigned Width,
bool NonNegative)
11934 : Width(Width), NonNegative(NonNegative) {}
11937 unsigned valueBits()
const {
11938 return NonNegative ? Width : Width - 1;
11942 static IntRange forBoolType() {
11943 return IntRange(1,
true);
11947 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11948 return forValueOfCanonicalType(
C,
11953 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11956 if (
const auto *VT = dyn_cast<VectorType>(
T))
11957 T = VT->getElementType().getTypePtr();
11958 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
11959 T = MT->getElementType().getTypePtr();
11960 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11961 T = CT->getElementType().getTypePtr();
11962 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11963 T = AT->getValueType().getTypePtr();
11964 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
11965 T = OBT->getUnderlyingType().getTypePtr();
11967 if (!
C.getLangOpts().CPlusPlus) {
11970 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11975 if (
Enum->isFixed()) {
11976 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11977 !
Enum->getIntegerType()->isSignedIntegerType());
11980 unsigned NumPositive =
Enum->getNumPositiveBits();
11981 unsigned NumNegative =
Enum->getNumNegativeBits();
11983 if (NumNegative == 0)
11984 return IntRange(NumPositive,
true);
11986 return IntRange(std::max(NumPositive + 1, NumNegative),
11990 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11991 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
12004 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
12007 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
12008 T = VT->getElementType().getTypePtr();
12009 if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T))
12010 T = MT->getElementType().getTypePtr();
12011 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
12012 T = CT->getElementType().getTypePtr();
12013 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
12014 T = AT->getValueType().getTypePtr();
12016 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
12017 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(
T))
12018 T = OBT->getUnderlyingType().getTypePtr();
12020 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
12021 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
12030 static IntRange
join(IntRange L, IntRange R) {
12031 bool Unsigned = L.NonNegative &&
R.NonNegative;
12032 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
12033 L.NonNegative &&
R.NonNegative);
12037 static IntRange bit_and(IntRange L, IntRange R) {
12038 unsigned Bits = std::max(L.Width,
R.Width);
12039 bool NonNegative =
false;
12040 if (L.NonNegative) {
12041 Bits = std::min(Bits, L.Width);
12042 NonNegative =
true;
12044 if (
R.NonNegative) {
12045 Bits = std::min(Bits,
R.Width);
12046 NonNegative =
true;
12048 return IntRange(Bits, NonNegative);
12052 static IntRange sum(IntRange L, IntRange R) {
12053 bool Unsigned = L.NonNegative &&
R.NonNegative;
12054 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
12059 static IntRange difference(IntRange L, IntRange R) {
12063 bool CanWiden = !L.NonNegative || !
R.NonNegative;
12064 bool Unsigned = L.NonNegative &&
R.Width == 0;
12065 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
12071 static IntRange product(IntRange L, IntRange R) {
12075 bool CanWiden = !L.NonNegative && !
R.NonNegative;
12076 bool Unsigned = L.NonNegative &&
R.NonNegative;
12077 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
12082 static IntRange rem(IntRange L, IntRange R) {
12086 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
12094 if (value.isSigned() && value.isNegative())
12095 return IntRange(value.getSignificantBits(),
false);
12097 if (value.getBitWidth() > MaxWidth)
12098 value = value.trunc(MaxWidth);
12102 return IntRange(value.getActiveBits(),
true);
12106 unsigned MaxWidth) {
12107 if (result.
isInt())
12111 std::optional<IntRange> R =
12114 return std::nullopt;
12116 std::optional<IntRange> El =
12119 return std::nullopt;
12120 R = IntRange::join(*R, *El);
12128 return IntRange::join(R, I);
12140 return std::nullopt;
12146 Ty = AtomicRHS->getValueType();
12165 bool InConstantContext,
12166 bool Approximate) {
12177 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
12178 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
12182 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
12184 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
12185 CE->getCastKind() == CK_BooleanToSignedIntegral;
12188 if (!isIntegerCast)
12189 return OutputTypeRange;
12192 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
12193 InConstantContext, Approximate);
12195 return std::nullopt;
12198 if (SubRange->Width >= OutputTypeRange.Width)
12199 return OutputTypeRange;
12203 return IntRange(SubRange->Width,
12204 SubRange->NonNegative || OutputTypeRange.NonNegative);
12207 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12210 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
12212 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
12213 InConstantContext, Approximate);
12218 Expr *TrueExpr = CO->getTrueExpr();
12220 return std::nullopt;
12222 std::optional<IntRange> L =
12225 return std::nullopt;
12227 Expr *FalseExpr = CO->getFalseExpr();
12229 return std::nullopt;
12231 std::optional<IntRange> R =
12234 return std::nullopt;
12236 return IntRange::join(*L, *R);
12239 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12240 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
12242 switch (BO->getOpcode()) {
12244 llvm_unreachable(
"builtin <=> should have class type");
12255 return IntRange::forBoolType();
12284 Combine = IntRange::bit_and;
12292 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
12293 if (I->getValue() == 1) {
12294 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
12295 return IntRange(R.Width,
true);
12305 case BO_ShrAssign: {
12307 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
12309 return std::nullopt;
12313 if (std::optional<llvm::APSInt> shift =
12314 BO->getRHS()->getIntegerConstantExpr(
C)) {
12315 if (shift->isNonNegative()) {
12316 if (shift->uge(L->Width))
12317 L->Width = (L->NonNegative ? 0 : 1);
12319 L->Width -= shift->getZExtValue();
12333 Combine = IntRange::sum;
12337 if (BO->getLHS()->getType()->isPointerType())
12340 Combine = IntRange::difference;
12345 Combine = IntRange::product;
12354 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
12356 return std::nullopt;
12359 if (std::optional<llvm::APSInt> divisor =
12360 BO->getRHS()->getIntegerConstantExpr(
C)) {
12361 unsigned log2 = divisor->logBase2();
12362 if (
log2 >= L->Width)
12363 L->Width = (L->NonNegative ? 0 : 1);
12365 L->Width = std::min(L->Width -
log2, MaxWidth);
12373 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
12375 return std::nullopt;
12377 return IntRange(L->Width, L->NonNegative && R->NonNegative);
12381 Combine = IntRange::rem;
12393 unsigned opWidth =
C.getIntWidth(
T);
12395 InConstantContext, Approximate);
12397 return std::nullopt;
12400 InConstantContext, Approximate);
12402 return std::nullopt;
12404 IntRange
C = Combine(*L, *R);
12405 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
12406 C.Width = std::min(
C.Width, MaxWidth);
12410 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
12411 switch (UO->getOpcode()) {
12414 return IntRange::forBoolType();
12422 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12428 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12431 return std::nullopt;
12436 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
12440 if (
GetExprType(E)->hasUnsignedIntegerRepresentation()) {
12446 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
12449 return std::nullopt;
12454 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
12464 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
12468 if (
const Expr *SourceExpr = OVE->getSourceExpr())
12474 return IntRange(BitField->getBitWidthValue(),
12475 BitField->getType()->isUnsignedIntegerOrEnumerationType());
12478 return std::nullopt;
12484 bool InConstantContext,
12485 bool Approximate) {
12494 const llvm::fltSemantics &Src,
12495 const llvm::fltSemantics &Tgt) {
12496 llvm::APFloat truncated = value;
12499 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12500 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12502 return truncated.bitwiseIsEqual(value);
12511 const llvm::fltSemantics &Src,
12512 const llvm::fltSemantics &Tgt) {
12536 bool IsListInit =
false);
12551 return MacroName !=
"YES" && MacroName !=
"NO" &&
12552 MacroName !=
"true" && MacroName !=
"false";
12560 (!E->
getType()->isSignedIntegerType() ||
12575struct PromotedRange {
12577 llvm::APSInt PromotedMin;
12579 llvm::APSInt PromotedMax;
12581 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12583 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12584 else if (
R.Width >= BitWidth && !
Unsigned) {
12588 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12589 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12591 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12592 .extOrTrunc(BitWidth);
12593 PromotedMin.setIsUnsigned(
Unsigned);
12595 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12596 .extOrTrunc(BitWidth);
12597 PromotedMax.setIsUnsigned(
Unsigned);
12602 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12612 InRangeFlag = 0x40,
12615 Min =
LE | InRangeFlag,
12616 InRange = InRangeFlag,
12617 Max =
GE | InRangeFlag,
12620 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12625 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12626 Value.isUnsigned() == PromotedMin.isUnsigned());
12627 if (!isContiguous()) {
12628 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12629 if (
Value.isMinValue())
return Min;
12630 if (
Value.isMaxValue())
return Max;
12631 if (
Value >= PromotedMin)
return InRange;
12632 if (
Value <= PromotedMax)
return InRange;
12636 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12637 case -1:
return Less;
12638 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12640 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12641 case -1:
return InRange;
12642 case 0:
return Max;
12647 llvm_unreachable(
"impossible compare result");
12650 static std::optional<StringRef>
12652 if (Op == BO_Cmp) {
12654 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12656 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12657 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12658 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12659 return std::nullopt;
12666 }
else if (Op == BO_NE) {
12670 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12677 if (Op == BO_GE || Op == BO_LE)
12678 std::swap(TrueFlag, FalseFlag);
12681 return StringRef(
"true");
12683 return StringRef(
"false");
12684 return std::nullopt;
12691 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12692 if (ICE->getCastKind() != CK_IntegralCast &&
12693 ICE->getCastKind() != CK_NoOp)
12695 E = ICE->getSubExpr();
12704 enum ConstantValueKind {
12709 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(
Constant))
12710 return BL->getValue() ? ConstantValueKind::LiteralTrue
12711 : ConstantValueKind::LiteralFalse;
12712 return ConstantValueKind::Miscellaneous;
12717 const llvm::APSInt &
Value,
12718 bool RhsConstant) {
12734 if (
Constant->getType()->isEnumeralType() &&
12740 if (!OtherValueRange)
12745 OtherT = AT->getValueType();
12746 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12750 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12756 bool OtherIsBooleanDespiteType =
12758 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12759 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12763 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12764 Value.isUnsigned());
12765 auto Cmp = OtherPromotedValueRange.compare(
Value);
12772 bool TautologicalTypeCompare =
false;
12774 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12775 Value.isUnsigned());
12776 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12779 TautologicalTypeCompare =
true;
12787 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12796 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12802 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12803 Other->getType()->isUnsignedIntegerOrEnumerationType())
12804 TautologicalTypeCompare =
true;
12809 if (
const auto *DR = dyn_cast<DeclRefExpr>(
Constant))
12810 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12814 llvm::raw_svector_ostream OS(PrettySourceValue);
12816 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12817 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12818 Constant->IgnoreParenImpCasts())) {
12819 OS << (BL->getValue() ?
"YES" :
"NO");
12824 if (!TautologicalTypeCompare) {
12826 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12832 if (IsObjCSignedCharBool) {
12834 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12835 << OS.str() << *
Result);
12842 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12846 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12847 : diag::warn_tautological_bool_compare)
12849 << OtherIsBooleanDespiteType << *
Result
12856 ? diag::warn_unsigned_enum_always_true_comparison
12857 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12858 : diag::warn_unsigned_always_true_comparison)
12859 : diag::warn_tautological_constant_compare;
12895 if (
T->isIntegralType(S.
Context)) {
12896 std::optional<llvm::APSInt> RHSValue =
12898 std::optional<llvm::APSInt> LHSValue =
12902 if (RHSValue && LHSValue)
12906 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12908 const bool RhsConstant = (
bool)RHSValue;
12909 Expr *Const = RhsConstant ? RHS : LHS;
12911 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12920 if (!
T->hasUnsignedIntegerRepresentation()) {
12934 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12936 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12942 Expr *signedOperand, *unsignedOperand;
12945 "unsigned comparison between two signed integer expressions?");
12946 signedOperand = LHS;
12947 unsignedOperand = RHS;
12949 signedOperand = RHS;
12950 unsignedOperand = LHS;
12956 std::optional<IntRange> signedRange =
12968 if (signedRange->NonNegative)
12980 if (!unsignedRange)
12985 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12987 if (unsignedRange->Width < comparisonWidth)
12992 S.
PDiag(diag::warn_mixed_sign_comparison)
13011 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
13016 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
13017 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
13018 BitfieldEnumDecl->getNumNegativeBits() == 0) {
13019 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
13020 << BitfieldEnumDecl;
13027 Init->isValueDependent() ||
13028 Init->isTypeDependent())
13031 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
13041 const PreferredTypeAttr *PTAttr =
nullptr;
13043 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
13045 ED = PTAttr->getType()->getAsEnumDecl();
13053 bool SignedEnum = ED->getNumNegativeBits() > 0;
13060 unsigned DiagID = 0;
13061 if (SignedEnum && !SignedBitfield) {
13064 ? diag::warn_unsigned_bitfield_assigned_signed_enum
13066 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
13067 }
else if (SignedBitfield && !SignedEnum &&
13068 ED->getNumPositiveBits() == FieldWidth) {
13071 ? diag::warn_signed_bitfield_enum_conversion
13072 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
13075 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
13080 << SignedEnum << TypeRange;
13082 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
13089 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
13090 ED->getNumNegativeBits())
13091 : ED->getNumPositiveBits();
13094 if (BitsNeeded > FieldWidth) {
13098 ? diag::warn_bitfield_too_small_for_enum
13099 : diag::warn_preferred_type_bitfield_too_small_for_enum;
13100 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
13104 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
13114 unsigned OriginalWidth =
Value.getBitWidth();
13120 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
13121 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
13128 if (!
Value.isSigned() ||
Value.isNegative())
13129 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
13130 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
13131 OriginalWidth =
Value.getSignificantBits();
13133 if (OriginalWidth <= FieldWidth)
13137 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
13141 TruncatedValue = TruncatedValue.extend(OriginalWidth);
13142 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
13146 std::string PrettyTrunc =
toString(TruncatedValue, 10);
13148 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
13149 ? diag::warn_impcast_single_bit_bitield_precision_constant
13150 : diag::warn_impcast_bitfield_precision_constant)
13151 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
13152 <<
Init->getSourceRange();
13189 bool PruneControlFlow =
false) {
13196 if (
T.hasAddressSpace())
13198 if (PruneControlFlow) {
13212 bool PruneControlFlow =
false) {
13219 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
13224 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
13225 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
13230 llvm::APFloat
Value(0.0);
13236 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
13241 diag::warn_impcast_float_integer, PruneWarnings);
13244 bool isExact =
false;
13247 T->hasUnsignedIntegerRepresentation());
13248 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
13249 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
13257 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
13258 precision = (precision * 59 + 195) / 196;
13259 Value.toString(PrettySourceValue, precision);
13263 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
13264 << PrettySourceValue);
13267 if (
Result == llvm::APFloat::opOK && isExact) {
13268 if (IsLiteral)
return;
13269 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
13275 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
13278 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
13279 : diag::warn_impcast_float_to_integer_out_of_range,
13282 unsigned DiagID = 0;
13285 DiagID = diag::warn_impcast_literal_float_to_integer;
13286 }
else if (IntegerValue == 0) {
13287 if (
Value.isZero()) {
13289 diag::warn_impcast_float_integer, PruneWarnings);
13292 DiagID = diag::warn_impcast_float_to_integer_zero;
13294 if (IntegerValue.isUnsigned()) {
13295 if (!IntegerValue.isMaxValue()) {
13297 diag::warn_impcast_float_integer, PruneWarnings);
13300 if (!IntegerValue.isMaxSignedValue() &&
13301 !IntegerValue.isMinSignedValue()) {
13303 diag::warn_impcast_float_integer, PruneWarnings);
13307 DiagID = diag::warn_impcast_float_to_integer;
13312 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
13314 IntegerValue.toString(PrettyTargetValue);
13316 if (PruneWarnings) {
13319 << E->
getType() <<
T.getUnqualifiedType()
13320 << PrettySourceValue << PrettyTargetValue
13324 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
13333 "Must be compound assignment operation");
13344 ->getComputationResultType()
13351 if (ResultBT->isInteger())
13353 E->
getExprLoc(), diag::warn_impcast_float_integer);
13355 if (!ResultBT->isFloatingPoint())
13364 diag::warn_impcast_float_result_precision);
13369 if (!Range.Width)
return "0";
13371 llvm::APSInt ValueInRange =
Value;
13372 ValueInRange.setIsSigned(!Range.NonNegative);
13373 ValueInRange = ValueInRange.trunc(Range.Width);
13374 return toString(ValueInRange, 10);
13384 const Type *Source =
13386 if (
Target->isDependentType())
13389 const auto *FloatCandidateBT =
13390 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
13391 const Type *BoolCandidateType = ToBool ?
Target : Source;
13394 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
13399 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
13405 S, TheCall->
getArg(I - 1),
false));
13407 S, TheCall->
getArg(I + 1),
false));
13412 diag::warn_impcast_floating_point_to_bool);
13427 if (!IsGNUNullExpr && !HasNullPtrType)
13431 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
13432 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
13435 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
13448 if (IsGNUNullExpr && Loc.
isMacroID()) {
13451 if (MacroName ==
"NULL")
13459 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
13474 const char FirstLiteralCharacter =
13476 if (FirstLiteralCharacter ==
'0')
13482 if (
T->isCharType() && !
T->isSignedIntegerType() && CC.
isValid()) {
13483 const char FirstContextCharacter =
13485 if (FirstContextCharacter ==
'{')
13493 const auto *IL = dyn_cast<IntegerLiteral>(E);
13495 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13496 if (UO->getOpcode() == UO_Minus)
13497 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13508 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13512 if (Opc == BO_Shl) {
13515 if (LHS && LHS->getValue() == 0)
13516 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13518 RHS->getValue().isNonNegative() &&
13520 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13521 << (
Result.Val.getInt() != 0);
13523 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13530 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13535 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13536 (RHS->getValue() == 0 || RHS->getValue() == 1))
13539 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13540 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13548 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13554 if (Source->isChar16Type() &&
Target->isChar32Type())
13560 llvm::APSInt
Value(32);
13562 bool IsASCII =
Value <= 0x7F;
13563 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13564 bool ConversionPreservesSemantics =
13565 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13567 if (!ConversionPreservesSemantics) {
13568 auto IsSingleCodeUnitCP = [](
const QualType &
T,
13569 const llvm::APSInt &
Value) {
13570 if (
T->isChar8Type())
13571 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13572 if (
T->isChar16Type())
13573 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13574 assert(
T->isChar32Type());
13575 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13578 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13587 LosesPrecision ? diag::warn_impcast_unicode_precision
13588 : diag::warn_impcast_unicode_char_type);
13593 From =
Context.getCanonicalType(From);
13594 To =
Context.getCanonicalType(To);
13597 From = MaybePointee;
13604 if (FromFn->getCFIUncheckedCalleeAttr() &&
13605 !ToFn->getCFIUncheckedCalleeAttr())
13613 bool *ICContext,
bool IsListInit) {
13618 if (Source ==
Target)
return;
13619 if (
Target->isDependentType())
return;
13629 if (Source->isAtomicType())
13633 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13639 diag::warn_impcast_string_literal_to_bool);
13645 diag::warn_impcast_objective_c_literal_to_bool);
13647 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13659 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
13662 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13664 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13673 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13675 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13686 diag::err_impcast_incompatible_type);
13691 ? diag::err_impcast_complex_scalar
13692 : diag::warn_impcast_complex_scalar);
13701 if (
Target->isSveVLSBuiltinType() &&
13708 if (
Target->isRVVVLSBuiltinType() &&
13718 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
13726 diag::warn_hlsl_impcast_vector_truncation);
13738 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13739 Target = VecTy->getElementType().getTypePtr();
13743 if (
Target->isScalarType())
13744 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
13752 diag::warn_hlsl_impcast_matrix_truncation);
13758 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13759 Target = MatTy->getElementType().getTypePtr();
13761 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13767 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
13770 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13772 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13819 else if (Order < 0) {
13829 if (TargetBT && TargetBT->
isInteger()) {
13856 diag::warn_impcast_floating_point_to_bool);
13864 if (Source->isFixedPointType()) {
13865 if (
Target->isUnsaturatedFixedPointType()) {
13869 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13870 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13871 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13874 PDiag(diag::warn_impcast_fixed_point_range)
13875 <<
Value.toString() <<
T
13881 }
else if (
Target->isIntegerType()) {
13885 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13888 llvm::APSInt IntResult = FXResult.convertToInt(
13889 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13894 PDiag(diag::warn_impcast_fixed_point_range)
13895 << FXResult.toString() <<
T
13902 }
else if (
Target->isUnsaturatedFixedPointType()) {
13903 if (Source->isIntegerType()) {
13910 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13915 PDiag(diag::warn_impcast_fixed_point_range)
13936 unsigned int SourcePrecision =
SourceRange->Width;
13940 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13943 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13944 SourcePrecision > TargetPrecision) {
13946 if (std::optional<llvm::APSInt> SourceInt =
13951 llvm::APFloat TargetFloatValue(
13953 llvm::APFloat::opStatus ConversionStatus =
13954 TargetFloatValue.convertFromAPInt(
13956 llvm::APFloat::rmNearestTiesToEven);
13958 if (ConversionStatus != llvm::APFloat::opOK) {
13960 SourceInt->toString(PrettySourceValue, 10);
13962 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13966 PDiag(diag::warn_impcast_integer_float_precision_constant)
13967 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13973 diag::warn_impcast_integer_float_precision);
13982 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13987 if (
Target->isBooleanType())
13991 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13995 if (!Source->isIntegerType() || !
Target->isIntegerType())
14000 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
14003 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
14006 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
14011 if (!LikelySourceRange)
14014 IntRange SourceTypeRange =
14015 IntRange::forTargetOfCanonicalType(
Context, Source);
14016 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
14018 if (LikelySourceRange->Width > TargetRange.Width) {
14022 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14023 if (TargetOBT->isWrapKind()) {
14030 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
14031 if (SourceOBT->isWrapKind()) {
14041 llvm::APSInt
Value(32);
14051 PDiag(diag::warn_impcast_integer_precision_constant)
14052 << PrettySourceValue << PrettyTargetValue
14062 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
14063 if (UO->getOpcode() == UO_Minus)
14065 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
14068 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
14072 diag::warn_impcast_integer_precision);
14075 if (TargetRange.Width > SourceTypeRange.Width) {
14076 if (
auto *UO = dyn_cast<UnaryOperator>(E))
14077 if (UO->getOpcode() == UO_Minus)
14078 if (Source->isUnsignedIntegerType()) {
14079 if (
Target->isUnsignedIntegerType())
14081 diag::warn_impcast_high_order_zero_bits);
14082 if (
Target->isSignedIntegerType())
14084 diag::warn_impcast_nonnegative_result);
14088 if (TargetRange.Width == LikelySourceRange->Width &&
14089 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
14090 Source->isSignedIntegerType()) {
14104 PDiag(diag::warn_impcast_integer_precision_constant)
14105 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
14115 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
14116 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
14117 LikelySourceRange->Width == TargetRange.Width))) {
14121 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
14123 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
14127 unsigned DiagID = diag::warn_impcast_integer_sign;
14135 DiagID = diag::warn_impcast_integer_sign_conditional;
14152 Source =
Context.getCanonicalType(SourceType).getTypePtr();
14154 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
14155 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
14156 if (SourceEnum->getDecl()->hasNameForLinkage() &&
14157 TargetEnum->getDecl()->hasNameForLinkage() &&
14158 SourceEnum != TargetEnum) {
14163 diag::warn_impcast_different_enum_types);
14177 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
14190 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
14191 TrueExpr = BCO->getCommon();
14193 bool Suspicious =
false;
14197 if (
T->isBooleanType())
14202 if (!Suspicious)
return;
14205 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
14212 Suspicious =
false;
14217 E->
getType(), CC, &Suspicious);
14234struct AnalyzeImplicitConversionsWorkItem {
14243 bool ExtraCheckForImplicitConversion,
14246 WorkList.push_back({E, CC,
false});
14248 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
14255 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
14257 Expr *OrigE = Item.E;
14276 Expr *SourceExpr = E;
14281 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
14282 if (
auto *Src = OVE->getSourceExpr())
14285 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
14286 if (UO->getOpcode() == UO_Not &&
14287 UO->getSubExpr()->isKnownToHaveBooleanValue())
14288 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
14292 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
14293 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
14294 BO->getLHS()->isKnownToHaveBooleanValue() &&
14295 BO->getRHS()->isKnownToHaveBooleanValue() &&
14296 BO->getLHS()->HasSideEffects(S.
Context) &&
14297 BO->getRHS()->HasSideEffects(S.
Context)) {
14308 if (SR.str() ==
"&" || SR.str() ==
"|") {
14310 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
14311 << (BO->getOpcode() == BO_And ?
"&" :
"|")
14314 BO->getOperatorLoc(),
14315 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
14316 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
14318 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
14336 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
14342 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
14357 for (
auto *SE : POE->semantics())
14358 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
14359 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
14363 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
14364 E = CE->getSubExpr();
14370 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
14371 if (InitListE->getNumInits() == 1) {
14372 E = InitListE->getInit(0);
14379 WorkList.push_back({E, CC, IsListInit});
14383 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
14384 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
14388 if (OutArgE->isInOut())
14389 WorkList.push_back(
14390 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
14391 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
14397 if (BO->isComparisonOp())
14401 if (BO->getOpcode() == BO_Assign)
14404 if (BO->isAssignmentOp())
14420 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
14422 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
14426 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
14427 if (ChildExpr == CSE->getOperand())
14433 if (IsLogicalAndOperator &&
14438 WorkList.push_back({ChildExpr, CC, IsListInit});
14452 if (
U->getOpcode() == UO_LNot) {
14454 }
else if (
U->getOpcode() != UO_AddrOf) {
14455 if (
U->getSubExpr()->getType()->isAtomicType())
14456 S.
Diag(
U->getSubExpr()->getBeginLoc(),
14457 diag::warn_atomic_implicit_seq_cst);
14468 WorkList.push_back({OrigE, CC, IsListInit});
14469 while (!WorkList.empty())
14481 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
14484 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14485 if (!M->getMemberDecl()->getType()->isReferenceType())
14487 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
14488 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
14490 FD =
Call->getDirectCallee();
14499 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14539 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14540 : diag::warn_this_bool_conversion;
14545 bool IsAddressOf =
false;
14547 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14548 if (UO->getOpcode() != UO_AddrOf)
14550 IsAddressOf =
true;
14551 E = UO->getSubExpr();
14555 unsigned DiagID = IsCompare
14556 ? diag::warn_address_of_reference_null_compare
14557 : diag::warn_address_of_reference_bool_conversion;
14565 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14568 llvm::raw_string_ostream S(Str);
14570 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14571 : diag::warn_cast_nonnull_to_bool;
14574 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14579 if (
auto *Callee =
Call->getDirectCallee()) {
14580 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14581 ComplainAboutNonnullParamOrCall(A);
14590 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14591 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14592 MRecordDecl && MRecordDecl->isLambda()) {
14595 << MRecordDecl->getSourceRange() << Range << IsEqual;
14605 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14606 D = M->getMemberDecl();
14614 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14617 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14618 ComplainAboutNonnullParamOrCall(A);
14622 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14626 auto ParamIter = llvm::find(FD->
parameters(), PV);
14628 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14632 ComplainAboutNonnullParamOrCall(
NonNull);
14637 if (ArgNo.getASTIndex() == ParamNo) {
14638 ComplainAboutNonnullParamOrCall(
NonNull);
14649 const bool IsFunctionReference =
14650 T->isReferenceType() &&
T->getPointeeType()->isFunctionType();
14651 if (IsFunctionReference)
14652 T =
T->getPointeeType();
14653 const bool IsArray =
T->isArrayType();
14654 const bool IsFunction =
T->isFunctionType();
14657 if (IsAddressOf && IsFunction) {
14662 if (!IsAddressOf && !IsFunction && !IsArray)
14667 llvm::raw_string_ostream S(Str);
14670 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14671 : diag::warn_impcast_pointer_to_bool;
14678 DiagType = AddressOf;
14679 else if (IsFunction)
14680 DiagType = FunctionPointer;
14682 DiagType = ArrayPointer;
14684 llvm_unreachable(
"Could not determine diagnostic.");
14686 << Range << IsEqual;
14689 if (!IsFunction || IsFunctionReference)
14700 if (ReturnType.
isNull())
14731 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14732 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14734 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14735 Target->isUnsignedIntegerType()) {
14739 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14740 : diag::warn_impcast_overflow_behavior_pedantic;
14744 ? diag::warn_impcast_overflow_behavior_assignment
14745 : diag::warn_impcast_overflow_behavior;
14751 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14752 if (TargetOBT->isWrapKind()) {
14772 CheckArrayAccess(E);
14782void Sema::CheckForIntOverflow (
const Expr *E) {
14784 SmallVector<const Expr *, 2> Exprs(1, E);
14787 const Expr *OriginalE = Exprs.pop_back_val();
14796 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14797 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14800 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14801 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14802 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14804 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14805 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14806 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14807 Exprs.push_back(Temporary->getSubExpr());
14808 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14809 Exprs.push_back(
Array->getIdx());
14810 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14811 Exprs.push_back(Compound->getInitializer());
14812 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14813 New &&
New->isArray()) {
14814 if (
auto ArraySize =
New->getArraySize())
14815 Exprs.push_back(*ArraySize);
14816 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14817 Exprs.push_back(MTE->getSubExpr());
14818 }
while (!Exprs.empty());
14826 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14833 class SequenceTree {
14835 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14836 unsigned Parent : 31;
14837 LLVM_PREFERRED_TYPE(
bool)
14838 unsigned Merged : 1;
14840 SmallVector<Value, 8> Values;
14846 friend class SequenceTree;
14850 explicit Seq(
unsigned N) : Index(N) {}
14853 Seq() : Index(0) {}
14856 SequenceTree() { Values.push_back(
Value(0)); }
14857 Seq root()
const {
return Seq(0); }
14862 Seq allocate(
Seq Parent) {
14863 Values.push_back(
Value(Parent.Index));
14864 return Seq(Values.size() - 1);
14869 Values[S.Index].Merged =
true;
14875 bool isUnsequenced(
Seq Cur,
Seq Old) {
14876 unsigned C = representative(Cur.Index);
14877 unsigned Target = representative(Old.Index);
14881 C = Values[
C].Parent;
14888 unsigned representative(
unsigned K) {
14889 if (Values[K].Merged)
14891 return Values[K].Parent = representative(Values[K].Parent);
14897 using Object =
const NamedDecl *;
14911 UK_ModAsSideEffect,
14913 UK_Count = UK_ModAsSideEffect + 1
14919 const Expr *UsageExpr =
nullptr;
14920 SequenceTree::Seq
Seq;
14926 Usage Uses[UK_Count];
14929 bool Diagnosed =
false;
14933 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14941 UsageInfoMap UsageMap;
14944 SequenceTree::Seq Region;
14948 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14952 SmallVectorImpl<const Expr *> &WorkList;
14959 struct SequencedSubexpression {
14960 SequencedSubexpression(SequenceChecker &
Self)
14961 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14962 Self.ModAsSideEffect = &ModAsSideEffect;
14965 ~SequencedSubexpression() {
14966 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14970 UsageInfo &UI =
Self.UsageMap[M.first];
14971 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14972 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14973 SideEffectUsage = M.second;
14975 Self.ModAsSideEffect = OldModAsSideEffect;
14978 SequenceChecker &
Self;
14979 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14980 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14987 class EvaluationTracker {
14989 EvaluationTracker(SequenceChecker &
Self)
14991 Self.EvalTracker =
this;
14994 ~EvaluationTracker() {
14995 Self.EvalTracker = Prev;
14997 Prev->EvalOK &= EvalOK;
15000 bool evaluate(
const Expr *E,
bool &
Result) {
15005 Self.SemaRef.isConstantEvaluatedContext());
15010 SequenceChecker &
Self;
15011 EvaluationTracker *Prev;
15012 bool EvalOK =
true;
15013 } *EvalTracker =
nullptr;
15017 Object getObject(
const Expr *E,
bool Mod)
const {
15019 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
15020 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
15021 return getObject(UO->getSubExpr(), Mod);
15022 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
15023 if (BO->getOpcode() == BO_Comma)
15024 return getObject(BO->getRHS(), Mod);
15025 if (Mod && BO->isAssignmentOp())
15026 return getObject(BO->getLHS(), Mod);
15027 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
15030 return ME->getMemberDecl();
15031 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
15040 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
15042 Usage &U = UI.Uses[UK];
15043 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
15047 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
15048 ModAsSideEffect->push_back(std::make_pair(O, U));
15050 U.UsageExpr = UsageExpr;
15060 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
15061 UsageKind OtherKind,
bool IsModMod) {
15065 const Usage &U = UI.Uses[OtherKind];
15066 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
15069 const Expr *Mod = U.UsageExpr;
15070 const Expr *ModOrUse = UsageExpr;
15071 if (OtherKind == UK_Use)
15072 std::swap(Mod, ModOrUse);
15076 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
15077 : diag::warn_unsequenced_mod_use)
15078 << O << SourceRange(ModOrUse->
getExprLoc()));
15079 UI.Diagnosed =
true;
15108 void notePreUse(
Object O,
const Expr *UseExpr) {
15109 UsageInfo &UI = UsageMap[O];
15111 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
15114 void notePostUse(
Object O,
const Expr *UseExpr) {
15115 UsageInfo &UI = UsageMap[O];
15116 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
15118 addUsage(O, UI, UseExpr, UK_Use);
15121 void notePreMod(
Object O,
const Expr *ModExpr) {
15122 UsageInfo &UI = UsageMap[O];
15124 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
15125 checkUsage(O, UI, ModExpr, UK_Use,
false);
15128 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
15129 UsageInfo &UI = UsageMap[O];
15130 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
15132 addUsage(O, UI, ModExpr, UK);
15136 SequenceChecker(Sema &S,
const Expr *E,
15137 SmallVectorImpl<const Expr *> &WorkList)
15138 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
15142 (void)this->WorkList;
15145 void VisitStmt(
const Stmt *S) {
15149 void VisitExpr(
const Expr *E) {
15151 Base::VisitStmt(E);
15154 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
15155 for (
auto *Sub : CSE->
children()) {
15156 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
15171 void VisitCastExpr(
const CastExpr *E) {
15183 void VisitSequencedExpressions(
const Expr *SequencedBefore,
15184 const Expr *SequencedAfter) {
15185 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
15186 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
15187 SequenceTree::Seq OldRegion = Region;
15190 SequencedSubexpression SeqBefore(*
this);
15191 Region = BeforeRegion;
15192 Visit(SequencedBefore);
15195 Region = AfterRegion;
15196 Visit(SequencedAfter);
15198 Region = OldRegion;
15200 Tree.merge(BeforeRegion);
15201 Tree.merge(AfterRegion);
15204 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
15209 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
15216 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15217 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
15218 void VisitBinPtrMem(
const BinaryOperator *BO) {
15223 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15230 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15231 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
15232 void VisitBinShlShr(
const BinaryOperator *BO) {
15236 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15243 void VisitBinComma(
const BinaryOperator *BO) {
15248 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
15251 void VisitBinAssign(
const BinaryOperator *BO) {
15252 SequenceTree::Seq RHSRegion;
15253 SequenceTree::Seq LHSRegion;
15255 RHSRegion = Tree.allocate(Region);
15256 LHSRegion = Tree.allocate(Region);
15258 RHSRegion = Region;
15259 LHSRegion = Region;
15261 SequenceTree::Seq OldRegion = Region;
15277 SequencedSubexpression SeqBefore(*
this);
15278 Region = RHSRegion;
15282 Region = LHSRegion;
15286 notePostUse(O, BO);
15290 Region = LHSRegion;
15294 notePostUse(O, BO);
15296 Region = RHSRegion;
15304 Region = OldRegion;
15308 : UK_ModAsSideEffect);
15310 Tree.merge(RHSRegion);
15311 Tree.merge(LHSRegion);
15315 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
15316 VisitBinAssign(CAO);
15319 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15320 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
15321 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
15324 return VisitExpr(UO);
15332 : UK_ModAsSideEffect);
15335 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15336 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
15337 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
15340 return VisitExpr(UO);
15344 notePostMod(O, UO, UK_ModAsSideEffect);
15347 void VisitBinLOr(
const BinaryOperator *BO) {
15353 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15354 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15355 SequenceTree::Seq OldRegion = Region;
15357 EvaluationTracker Eval(*
this);
15359 SequencedSubexpression Sequenced(*
this);
15360 Region = LHSRegion;
15367 bool EvalResult =
false;
15368 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15369 bool ShouldVisitRHS = !EvalOK || !EvalResult;
15370 if (ShouldVisitRHS) {
15371 Region = RHSRegion;
15375 Region = OldRegion;
15376 Tree.merge(LHSRegion);
15377 Tree.merge(RHSRegion);
15380 void VisitBinLAnd(
const BinaryOperator *BO) {
15386 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
15387 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
15388 SequenceTree::Seq OldRegion = Region;
15390 EvaluationTracker Eval(*
this);
15392 SequencedSubexpression Sequenced(*
this);
15393 Region = LHSRegion;
15399 bool EvalResult =
false;
15400 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
15401 bool ShouldVisitRHS = !EvalOK || EvalResult;
15402 if (ShouldVisitRHS) {
15403 Region = RHSRegion;
15407 Region = OldRegion;
15408 Tree.merge(LHSRegion);
15409 Tree.merge(RHSRegion);
15412 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
15417 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
15433 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
15434 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
15435 SequenceTree::Seq OldRegion = Region;
15437 EvaluationTracker Eval(*
this);
15439 SequencedSubexpression Sequenced(*
this);
15440 Region = ConditionRegion;
15450 bool EvalResult =
false;
15451 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
15452 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
15453 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
15454 if (ShouldVisitTrueExpr) {
15455 Region = TrueRegion;
15458 if (ShouldVisitFalseExpr) {
15459 Region = FalseRegion;
15463 Region = OldRegion;
15464 Tree.merge(ConditionRegion);
15465 Tree.merge(TrueRegion);
15466 Tree.merge(FalseRegion);
15469 void VisitCallExpr(
const CallExpr *CE) {
15481 SequencedSubexpression Sequenced(*
this);
15486 SequenceTree::Seq CalleeRegion;
15487 SequenceTree::Seq OtherRegion;
15488 if (SemaRef.getLangOpts().CPlusPlus17) {
15489 CalleeRegion = Tree.allocate(Region);
15490 OtherRegion = Tree.allocate(Region);
15492 CalleeRegion = Region;
15493 OtherRegion = Region;
15495 SequenceTree::Seq OldRegion = Region;
15498 Region = CalleeRegion;
15500 SequencedSubexpression Sequenced(*this);
15501 Visit(CE->getCallee());
15503 Visit(CE->getCallee());
15507 Region = OtherRegion;
15511 Region = OldRegion;
15513 Tree.merge(CalleeRegion);
15514 Tree.merge(OtherRegion);
15532 return VisitCallExpr(CXXOCE);
15543 case OO_MinusEqual:
15545 case OO_SlashEqual:
15546 case OO_PercentEqual:
15547 case OO_CaretEqual:
15550 case OO_LessLessEqual:
15551 case OO_GreaterGreaterEqual:
15552 SequencingKind = RHSBeforeLHS;
15556 case OO_GreaterGreater:
15562 SequencingKind = LHSBeforeRHS;
15566 SequencingKind = LHSBeforeRest;
15570 SequencingKind = NoSequencing;
15574 if (SequencingKind == NoSequencing)
15575 return VisitCallExpr(CXXOCE);
15578 SequencedSubexpression Sequenced(*
this);
15581 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15582 "Should only get there with C++17 and above!");
15583 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15584 "Should only get there with an overloaded binary operator"
15585 " or an overloaded call operator!");
15587 if (SequencingKind == LHSBeforeRest) {
15588 assert(CXXOCE->getOperator() == OO_Call &&
15589 "We should only have an overloaded call operator here!");
15598 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15599 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15600 SequenceTree::Seq OldRegion = Region;
15602 assert(CXXOCE->getNumArgs() >= 1 &&
15603 "An overloaded call operator must have at least one argument"
15604 " for the postfix-expression!");
15605 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15606 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15607 CXXOCE->getNumArgs() - 1);
15611 Region = PostfixExprRegion;
15612 SequencedSubexpression Sequenced(*this);
15613 Visit(PostfixExpr);
15617 Region = ArgsRegion;
15618 for (const Expr *Arg : Args)
15621 Region = OldRegion;
15622 Tree.merge(PostfixExprRegion);
15623 Tree.merge(ArgsRegion);
15625 assert(CXXOCE->getNumArgs() == 2 &&
15626 "Should only have two arguments here!");
15627 assert((SequencingKind == LHSBeforeRHS ||
15628 SequencingKind == RHSBeforeLHS) &&
15629 "Unexpected sequencing kind!");
15633 const Expr *E1 = CXXOCE->getArg(0);
15634 const Expr *E2 = CXXOCE->getArg(1);
15635 if (SequencingKind == RHSBeforeLHS)
15638 return VisitSequencedExpressions(E1, E2);
15645 SequencedSubexpression Sequenced(*
this);
15648 return VisitExpr(CCE);
15651 SequenceExpressionsInOrder(
15657 return VisitExpr(ILE);
15660 SequenceExpressionsInOrder(ILE->
inits());
15672 SequenceTree::Seq Parent = Region;
15673 for (
const Expr *E : ExpressionList) {
15676 Region = Tree.allocate(Parent);
15677 Elts.push_back(Region);
15683 for (
unsigned I = 0; I < Elts.size(); ++I)
15684 Tree.merge(Elts[I]);
15688SequenceChecker::UsageInfo::UsageInfo() =
default;
15692void Sema::CheckUnsequencedOperations(
const Expr *E) {
15693 SmallVector<const Expr *, 8> WorkList;
15694 WorkList.push_back(E);
15695 while (!WorkList.empty()) {
15696 const Expr *Item = WorkList.pop_back_val();
15697 SequenceChecker(*
this, Item, WorkList);
15702 bool IsConstexpr) {
15705 CheckImplicitConversions(E, CheckLoc);
15707 CheckUnsequencedOperations(E);
15709 CheckForIntOverflow(E);
15722 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15726 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15730 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15744 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15748 bool CheckParameterNames) {
15749 bool HasInvalidParm =
false;
15751 assert(Param &&
"null in a parameter list");
15760 if (!Param->isInvalidDecl() &&
15762 diag::err_typecheck_decl_incomplete_type) ||
15764 diag::err_abstract_type_in_decl,
15766 Param->setInvalidDecl();
15767 HasInvalidParm =
true;
15772 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15776 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15784 QualType PType = Param->getOriginalType();
15792 if (!Param->isInvalidDecl()) {
15793 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15794 if (!ClassDecl->isInvalidDecl() &&
15795 !ClassDecl->hasIrrelevantDestructor() &&
15796 !ClassDecl->isDependentContext() &&
15797 ClassDecl->isParamDestroyedInCallee()) {
15809 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15810 if (!Param->getType().isConstQualified())
15811 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15815 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15820 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15821 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15826 if (!Param->isInvalidDecl() &&
15827 Param->getOriginalType()->isWebAssemblyTableType()) {
15828 Param->setInvalidDecl();
15829 HasInvalidParm =
true;
15830 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15834 return HasInvalidParm;
15837std::optional<std::pair<
15846static std::pair<CharUnits, CharUnits>
15854 if (
Base->isVirtual()) {
15861 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15868 DerivedType =
Base->getType();
15871 return std::make_pair(BaseAlignment, Offset);
15875static std::optional<std::pair<CharUnits, CharUnits>>
15881 return std::nullopt;
15886 return std::nullopt;
15890 CharUnits Offset = EltSize * IdxRes->getExtValue();
15893 return std::make_pair(P->first, P->second + Offset);
15899 return std::make_pair(
15900 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15906std::optional<std::pair<
15914 case Stmt::CStyleCastExprClass:
15915 case Stmt::CXXStaticCastExprClass:
15916 case Stmt::ImplicitCastExprClass: {
15918 const Expr *From = CE->getSubExpr();
15919 switch (CE->getCastKind()) {
15924 case CK_UncheckedDerivedToBase:
15925 case CK_DerivedToBase: {
15935 case Stmt::ArraySubscriptExprClass: {
15940 case Stmt::DeclRefExprClass: {
15944 if (!VD->getType()->isReferenceType()) {
15946 if (VD->hasDependentAlignment())
15955 case Stmt::MemberExprClass: {
15957 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15961 std::optional<std::pair<CharUnits, CharUnits>> P;
15970 return std::make_pair(P->first,
15973 case Stmt::UnaryOperatorClass: {
15983 case Stmt::BinaryOperatorClass: {
15995 return std::nullopt;
16000std::optional<std::pair<
16009 case Stmt::CStyleCastExprClass:
16010 case Stmt::CXXStaticCastExprClass:
16011 case Stmt::ImplicitCastExprClass: {
16013 const Expr *From = CE->getSubExpr();
16014 switch (CE->getCastKind()) {
16019 case CK_ArrayToPointerDecay:
16021 case CK_UncheckedDerivedToBase:
16022 case CK_DerivedToBase: {
16032 case Stmt::CXXThisExprClass: {
16037 case Stmt::UnaryOperatorClass: {
16043 case Stmt::BinaryOperatorClass: {
16052 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
16053 std::swap(LHS, RHS);
16063 return std::nullopt;
16068 std::optional<std::pair<CharUnits, CharUnits>> P =
16072 return P->first.alignmentAtOffset(P->second);
16090 if (!DestPtr)
return;
16096 if (DestAlign.
isOne())
return;
16100 if (!SrcPtr)
return;
16111 if (SrcAlign >= DestAlign)
return;
16116 <<
static_cast<unsigned>(DestAlign.
getQuantity())
16120void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
16122 bool AllowOnePastEnd,
bool IndexNegated) {
16131 const Type *EffectiveType =
16135 Context.getAsConstantArrayType(BaseExpr->
getType());
16138 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
16140 const Type *BaseType =
16142 bool IsUnboundedArray =
16144 Context, StrictFlexArraysLevel,
16147 (!IsUnboundedArray && BaseType->isDependentType()))
16155 if (IndexNegated) {
16156 index.setIsUnsigned(
false);
16160 if (IsUnboundedArray) {
16163 if (
index.isUnsigned() || !
index.isNegative()) {
16165 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
16167 if (
index.getBitWidth() < AddrBits)
16169 std::optional<CharUnits> ElemCharUnits =
16170 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
16173 if (!ElemCharUnits || ElemCharUnits->isZero())
16175 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
16180 if (
index.getActiveBits() <= AddrBits) {
16182 llvm::APInt Product(
index);
16184 Product = Product.umul_ov(ElemBytes, Overflow);
16185 if (!Overflow && Product.getActiveBits() <= AddrBits)
16191 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
16192 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
16194 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
16195 MaxElems = MaxElems.udiv(ElemBytes);
16198 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
16199 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
16204 PDiag(DiagID) << index << AddrBits
16205 << (
unsigned)ASTC.toBits(*ElemCharUnits)
16206 << ElemBytes << MaxElems
16207 << MaxElems.getZExtValue()
16210 const NamedDecl *ND =
nullptr;
16212 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16214 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16216 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16217 ND = ME->getMemberDecl();
16221 PDiag(diag::note_array_declared_here) << ND);
16226 if (index.isUnsigned() || !index.isNegative()) {
16236 llvm::APInt size = ArrayTy->
getSize();
16238 if (BaseType != EffectiveType) {
16246 if (!ptrarith_typesize)
16247 ptrarith_typesize =
Context.getCharWidth();
16249 if (ptrarith_typesize != array_typesize) {
16251 uint64_t ratio = array_typesize / ptrarith_typesize;
16255 if (ptrarith_typesize * ratio == array_typesize)
16256 size *= llvm::APInt(size.getBitWidth(), ratio);
16260 if (size.getBitWidth() > index.getBitWidth())
16261 index = index.zext(size.getBitWidth());
16262 else if (size.getBitWidth() < index.getBitWidth())
16263 size = size.zext(index.getBitWidth());
16269 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
16276 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
16278 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
16279 SourceLocation IndexLoc =
16281 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
16286 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
16287 : diag::warn_ptr_arith_exceeds_bounds;
16288 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
16289 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
16293 << index << ArrayTy->
desugar() << CastMsg
16296 unsigned DiagID = diag::warn_array_index_precedes_bounds;
16298 DiagID = diag::warn_ptr_arith_precedes_bounds;
16299 if (index.isNegative()) index = -index;
16306 const NamedDecl *ND =
nullptr;
16308 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
16310 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
16312 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
16313 ND = ME->getMemberDecl();
16317 PDiag(diag::note_array_declared_here) << ND);
16320void Sema::CheckArrayAccess(
const Expr *
expr) {
16321 int AllowOnePastEnd = 0;
16323 expr =
expr->IgnoreParenImpCasts();
16324 switch (
expr->getStmtClass()) {
16325 case Stmt::ArraySubscriptExprClass: {
16328 AllowOnePastEnd > 0);
16332 case Stmt::MemberExprClass: {
16336 case Stmt::CXXMemberCallExprClass: {
16340 case Stmt::ArraySectionExprClass: {
16346 nullptr, AllowOnePastEnd > 0);
16349 case Stmt::UnaryOperatorClass: {
16365 case Stmt::ConditionalOperatorClass: {
16367 if (
const Expr *lhs = cond->
getLHS())
16368 CheckArrayAccess(lhs);
16369 if (
const Expr *rhs = cond->
getRHS())
16370 CheckArrayAccess(rhs);
16373 case Stmt::CXXOperatorCallExprClass: {
16375 for (
const auto *Arg : OCE->arguments())
16376 CheckArrayAccess(Arg);
16386 Expr *RHS,
bool isProperty) {
16398 S.
Diag(Loc, diag::warn_arc_literal_assign)
16400 << (isProperty ? 0 : 1)
16408 Expr *RHS,
bool isProperty) {
16411 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16412 S.
Diag(Loc, diag::warn_arc_retained_assign)
16414 << (isProperty ? 0 : 1)
16418 RHS =
cast->getSubExpr();
16460 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
16489 if (
cast->getCastKind() == CK_ARCConsumeObject) {
16490 Diag(Loc, diag::warn_arc_retained_property_assign)
16494 RHS =
cast->getSubExpr();
16517 bool StmtLineInvalid;
16518 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16520 if (StmtLineInvalid)
16523 bool BodyLineInvalid;
16524 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16526 if (BodyLineInvalid)
16530 if (StmtLine != BodyLine)
16545 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16554 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16558 const Stmt *PossibleBody) {
16564 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16565 StmtLoc = FS->getRParenLoc();
16566 Body = FS->getBody();
16567 DiagID = diag::warn_empty_for_body;
16568 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16569 StmtLoc = WS->getRParenLoc();
16570 Body = WS->getBody();
16571 DiagID = diag::warn_empty_while_body;
16576 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16600 if (!ProbableTypo) {
16601 bool BodyColInvalid;
16602 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16604 if (BodyColInvalid)
16607 bool StmtColInvalid;
16610 if (StmtColInvalid)
16613 if (BodyCol > StmtCol)
16614 ProbableTypo =
true;
16617 if (ProbableTypo) {
16619 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16627 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16639 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16641 RHSExpr = CE->
getArg(0);
16642 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16643 CXXSCE && CXXSCE->isXValue())
16644 RHSExpr = CXXSCE->getSubExpr();
16648 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16649 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16652 if (LHSDeclRef && RHSDeclRef) {
16659 auto D =
Diag(OpLoc, diag::warn_self_move)
16675 const Expr *LHSBase = LHSExpr;
16676 const Expr *RHSBase = RHSExpr;
16677 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16678 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16679 if (!LHSME || !RHSME)
16682 while (LHSME && RHSME) {
16689 LHSME = dyn_cast<MemberExpr>(LHSBase);
16690 RHSME = dyn_cast<MemberExpr>(RHSBase);
16693 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16694 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16695 if (LHSDeclRef && RHSDeclRef) {
16702 Diag(OpLoc, diag::warn_self_move)
16709 Diag(OpLoc, diag::warn_self_move)
16733 bool AreUnionMembers =
false) {
16737 assert(((Field1Parent->isStructureOrClassType() &&
16738 Field2Parent->isStructureOrClassType()) ||
16739 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16740 "Can't evaluate layout compatibility between a struct field and a "
16742 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16743 (AreUnionMembers && Field1Parent->isUnionType())) &&
16744 "AreUnionMembers should be 'true' for union fields (only).");
16758 if (Bits1 != Bits2)
16762 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16763 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16766 if (!AreUnionMembers &&
16778 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16779 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16781 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16782 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16787 return isLayoutCompatible(C, F1, F2);
16798 for (
auto *Field1 : RD1->
fields()) {
16799 auto It = llvm::find_if(UnmatchedFields, [&](
const FieldDecl *Field2) {
16802 if (It == UnmatchedFields.end())
16804 [[maybe_unused]]
bool Result = UnmatchedFields.erase(*It);
16808 return UnmatchedFields.empty();
16834 if (
C.hasSameType(T1, T2))
16843 if (TC1 == Type::Enum)
16845 if (TC1 == Type::Record) {
16864 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16895 const ValueDecl **VD, uint64_t *MagicValue,
16896 bool isConstantEvaluated) {
16904 case Stmt::UnaryOperatorClass: {
16913 case Stmt::DeclRefExprClass: {
16919 case Stmt::IntegerLiteralClass: {
16921 llvm::APInt MagicValueAPInt = IL->
getValue();
16922 if (MagicValueAPInt.getActiveBits() <= 64) {
16923 *MagicValue = MagicValueAPInt.getZExtValue();
16929 case Stmt::BinaryConditionalOperatorClass:
16930 case Stmt::ConditionalOperatorClass: {
16935 isConstantEvaluated)) {
16945 case Stmt::BinaryOperatorClass: {
16948 TypeExpr = BO->
getRHS();
16978 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16981 bool isConstantEvaluated) {
16982 FoundWrongKind =
false;
16987 uint64_t MagicValue;
16989 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16993 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16994 if (I->getArgumentKind() != ArgumentKind) {
16995 FoundWrongKind =
true;
16998 TypeInfo.Type = I->getMatchingCType();
16999 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
17000 TypeInfo.MustBeNull = I->getMustBeNull();
17011 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
17012 if (I == MagicValues->end())
17021 bool LayoutCompatible,
17023 if (!TypeTagForDatatypeMagicValues)
17024 TypeTagForDatatypeMagicValues.reset(
17025 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
17028 (*TypeTagForDatatypeMagicValues)[Magic] =
17044 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
17045 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
17046 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
17047 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
17050void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
17053 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
17054 bool IsPointerAttr = Attr->getIsPointer();
17057 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
17058 if (TypeTagIdxAST >= ExprArgs.size()) {
17059 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
17060 << 0 << Attr->getTypeTagIdx().getSourceIndex();
17063 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
17064 bool FoundWrongKind;
17067 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
17069 if (FoundWrongKind)
17071 diag::warn_type_tag_for_datatype_wrong_kind)
17077 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
17078 if (ArgumentIdxAST >= ExprArgs.size()) {
17079 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
17080 << 1 << Attr->getArgumentIdx().getSourceIndex();
17083 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
17084 if (IsPointerAttr) {
17086 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
17087 if (ICE->getType()->isVoidPointerType() &&
17088 ICE->getCastKind() == CK_BitCast)
17089 ArgumentExpr = ICE->getSubExpr();
17091 QualType ArgumentType = ArgumentExpr->
getType();
17097 if (TypeInfo.MustBeNull) {
17102 diag::warn_type_safety_null_pointer_required)
17110 QualType RequiredType = TypeInfo.Type;
17112 RequiredType =
Context.getPointerType(RequiredType);
17114 bool mismatch =
false;
17115 if (!TypeInfo.LayoutCompatible) {
17116 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
17137 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
17138 << ArgumentType << ArgumentKind
17139 << TypeInfo.LayoutCompatible << RequiredType
17157 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
17165 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
17171 auto &MisalignedMembersForExpr =
17173 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
17174 if (MA != MisalignedMembersForExpr.end() &&
17175 (
T->isDependentType() ||
T->isIntegerType() ||
17176 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
17178 T->getPointeeType()) <= MA->Alignment))))
17179 MisalignedMembersForExpr.erase(MA);
17188 const auto *ME = dyn_cast<MemberExpr>(E);
17200 bool AnyIsPacked =
false;
17202 QualType BaseType = ME->getBase()->getType();
17203 if (BaseType->isDependentType())
17207 auto *RD = BaseType->castAsRecordDecl();
17212 auto *FD = dyn_cast<FieldDecl>(MD);
17218 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
17219 ReverseMemberChain.push_back(FD);
17222 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
17224 assert(TopME &&
"We did not compute a topmost MemberExpr!");
17231 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
17242 if (ExpectedAlignment.
isOne())
17247 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
17248 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
17252 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
17256 if (DRE && !TopME->
isArrow()) {
17259 CompleteObjectAlignment =
17260 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
17264 if (!Offset.isMultipleOf(ExpectedAlignment) ||
17267 CompleteObjectAlignment < ExpectedAlignment) {
17278 for (
FieldDecl *FDI : ReverseMemberChain) {
17279 if (FDI->hasAttr<PackedAttr>() ||
17280 FDI->getParent()->hasAttr<PackedAttr>()) {
17282 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
17288 assert(FD &&
"We did not find a packed FieldDecl!");
17289 Action(E, FD->
getParent(), FD, Alignment);
17293void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
17294 using namespace std::placeholders;
17297 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
17321bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
17322 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
17349 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
17366 assert(!Args.empty() &&
"Should have at least one argument.");
17368 Expr *Arg0 = Args.front();
17371 auto EmitError = [&](
Expr *ArgI) {
17373 diag::err_typecheck_call_different_arg_types)
17374 << Arg0->
getType() << ArgI->getType();
17379 for (
Expr *ArgI : Args.drop_front())
17390 for (
Expr *ArgI : Args.drop_front()) {
17391 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
17394 VecI->getElementType()) ||
17395 Vec0->getNumElements() != VecI->getNumElements()) {
17404std::optional<QualType>
17408 return std::nullopt;
17412 return std::nullopt;
17415 for (
int I = 0; I < 2; ++I) {
17419 return std::nullopt;
17420 Args[I] = Converted.
get();
17427 return std::nullopt;
17430 return std::nullopt;
17432 TheCall->
setArg(0, Args[0]);
17433 TheCall->
setArg(1, Args[1]);
17444 TheCall->
getArg(1), Loc) ||
17446 TheCall->
getArg(2), Loc))
17450 for (
int I = 0; I < 3; ++I) {
17455 Args[I] = Converted.
get();
17458 int ArgOrdinal = 1;
17459 for (
Expr *Arg : Args) {
17461 ArgTyRestr, ArgOrdinal++))
17468 for (
int I = 0; I < 3; ++I)
17469 TheCall->
setArg(I, Args[I]);
17475bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
17487bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17496 diag::err_builtin_invalid_arg_type)
17497 << 1 << 2 << 1 << 1 << TyArg;
17511 Expr *Matrix = MatrixArg.
get();
17513 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17516 << 1 << 3 << 0 << 0
17523 QualType ResultType =
Context.getConstantMatrixType(
17524 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17527 TheCall->
setType(ResultType);
17530 TheCall->
setArg(0, Matrix);
17535static std::optional<unsigned>
17543 uint64_t
Dim =
Value->getZExtValue();
17559 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17561 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17569 unsigned PtrArgIdx = 0;
17570 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17571 Expr *RowsExpr = TheCall->
getArg(1);
17572 Expr *ColumnsExpr = TheCall->
getArg(2);
17573 Expr *StrideExpr = TheCall->
getArg(3);
17575 bool ArgError =
false;
17582 PtrExpr = PtrConv.
get();
17583 TheCall->
setArg(0, PtrExpr);
17590 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17591 QualType ElementTy;
17594 << PtrArgIdx + 1 << 0 << 5 << 0
17598 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17602 << PtrArgIdx + 1 << 0 << 5
17609 auto ApplyArgumentConversions = [
this](Expr *E) {
17618 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17620 RowsExpr = RowsConv.
get();
17621 TheCall->
setArg(1, RowsExpr);
17623 RowsExpr =
nullptr;
17625 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17627 ColumnsExpr = ColumnsConv.
get();
17628 TheCall->
setArg(2, ColumnsExpr);
17630 ColumnsExpr =
nullptr;
17641 std::optional<unsigned> MaybeRows;
17645 std::optional<unsigned> MaybeColumns;
17650 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17653 StrideExpr = StrideConv.
get();
17654 TheCall->
setArg(3, StrideExpr);
17657 if (std::optional<llvm::APSInt>
Value =
17660 if (Stride < *MaybeRows) {
17662 diag::err_builtin_matrix_stride_too_small);
17668 if (ArgError || !MaybeRows || !MaybeColumns)
17672 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17683 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17685 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17693 unsigned PtrArgIdx = 1;
17694 Expr *MatrixExpr = TheCall->
getArg(0);
17695 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17696 Expr *StrideExpr = TheCall->
getArg(2);
17698 bool ArgError =
false;
17704 MatrixExpr = MatrixConv.
get();
17705 TheCall->
setArg(0, MatrixExpr);
17712 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17715 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17723 PtrExpr = PtrConv.
get();
17724 TheCall->
setArg(1, PtrExpr);
17732 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17735 << PtrArgIdx + 1 << 0 << 5 << 0
17739 QualType ElementTy = PtrTy->getPointeeType();
17741 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17746 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17748 diag::err_builtin_matrix_pointer_arg_mismatch)
17749 << ElementTy << MatrixTy->getElementType();
17764 StrideExpr = StrideConv.
get();
17765 TheCall->
setArg(2, StrideExpr);
17770 if (std::optional<llvm::APSInt>
Value =
17773 if (Stride < MatrixTy->getNumRows()) {
17775 diag::err_builtin_matrix_stride_too_small);
17795 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17800 llvm::StringSet<> CalleeTCBs;
17801 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17802 CalleeTCBs.insert(A->getTCBName());
17803 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17804 CalleeTCBs.insert(A->getTCBName());
17808 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17809 StringRef CallerTCB = A->getTCBName();
17810 if (CalleeTCBs.count(CallerTCB) == 0) {
17811 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17812 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
Defines enumerations for traits support.
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.
Result
Implement __builtin_bit_cast and related operations.
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
llvm::MachO::Record Record
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 getFunctionName(const CallEvent &Call)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
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 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 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 BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
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 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 isValidMathElementType(QualType T)
static void DiagnoseDeprecatedHIPAtomic(Sema &S, SourceRange ExprRange, MultiExprArg Args, AtomicExpr::AtomicOp Op)
Deprecate __hip_atomic_* builtins in favour of __scoped_atomic_* equivalents.
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)
#define HIP_ATOMIC_FIXABLE(hip, scoped)
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 QualType getVectorElementType(ASTContext &Context, QualType VecTy)
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 bool BuiltinBitreverseg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bitreverseg was called with a single argument, which is an integer.
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 bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
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 ExprResult PointerAuthAuthWithPCAndResign(Sema &S, CallExpr *Call)
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 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, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
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 CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
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 ConvertMaskedBuiltinArgs(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 ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
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 for SYCL 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.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
static bool hasLayout(const RecordDecl *D)
Whether layout (offset and size) information can be queried for D.
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 * getStart() const
StringRef toString() 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
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
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],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APValue & getMatrixElt(unsigned Idx)
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
unsigned getMatrixNumElements() const
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
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
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
const LangOptions & getLangOpts() const
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
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.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
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.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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
llvm::SmallString< 64 > 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++ conversion function within a class.
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 byte-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
bool isOne() const
Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits 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)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
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
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
DeclContext * getEnclosingNonExpansionStatementContext()
Retrieve the innermost enclosing context that doesn't belong to an expansion statement.
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
SourceLocation getEndLoc() const LLVM_READONLY
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 hasUnrecoverableErrorOccurred() const
Determine whether any unrecoverable 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,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
@ 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.
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...
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 * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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 ...
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
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.
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() const
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.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
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
ARM8_3Key
Hardware pointer-signing keys in ARM8.3.
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 isVolatileQualified() const
Determine whether this type is volatile-qualified.
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.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
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 hasFlexibleArrayMember() const
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(const TargetInfo &TI, 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.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a 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)
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
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.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
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 PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
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...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
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)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
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 pushCodeSynthesisContext(CodeSynthesisContext Ctx)
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 convertArgumentToType(Expr *&Value, QualType Ty)
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...
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 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 FormatStringI...
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.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
bool isMacroArgExpansion(SourceLocation Loc, SourceLocation *StartLoc=nullptr) const
Tests whether the given source location represents a macro argument's expansion into the function-lik...
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
SourceLocation getImmediateMacroCallerLoc(SourceLocation Loc) const
Gets the location of the immediate macro caller, one level up the stack toward the initial macro type...
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
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 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 isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
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 isAnyComplexType() 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 isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isMatrixType() 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
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 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
bool isSizelessVectorType() const
Returns true for all scalable vector types.
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
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
const clang::Expr * ExprTy
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)
SetTy< T > join(SetTy< T > A, SetTy< T > B, typename SetTy< T >::Factory &F)
Computes the union of two ImmutableSets.
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
Top level wrappers for InstallAPI frontend operations.
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
bool isFunctionOrMethodVariadic(const Decl *D)
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
unsigned getFunctionOrMethodNumParams(const Decl *D, bool IncludeThis=false)
getFunctionOrMethodNumParams - Return number of function or method parameters, optionally including t...
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
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.
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 int64_t
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 Indentation
The number of spaces to use to indent each line.
unsigned AnonymousTagNameStyle
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.