Index: include/clang/Basic/Builtins.def =================================================================== --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -953,6 +953,7 @@ LIBBUILTIN(index, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(rindex, "c*cC*i", "f", "strings.h", ALL_GNU_LANGUAGES) LIBBUILTIN(bzero, "vv*z", "f", "strings.h", ALL_GNU_LANGUAGES) +LIBBUILTIN(bcmp, "iv*v*z", "f", "strings.h", ALL_GNU_LANGUAGES) // In some systems str[n]casejmp is a macro that expands to _str[n]icmp. // We undefine then here to avoid wrong name. #undef strcasecmp Index: lib/AST/Decl.cpp =================================================================== --- lib/AST/Decl.cpp +++ lib/AST/Decl.cpp @@ -3672,6 +3672,10 @@ case Builtin::BImemcmp: return Builtin::BImemcmp; + case Builtin::BI__builtin_bcmp: + case Builtin::BIbcmp: + return Builtin::BIbcmp; + case Builtin::BI__builtin_strncpy: case Builtin::BI__builtin___strncpy_chk: case Builtin::BIstrncpy: @@ -3712,6 +3716,8 @@ return Builtin::BImemmove; else if (FnInfo->isStr("memcmp")) return Builtin::BImemcmp; + else if (FnInfo->isStr("bcmp")) + return Builtin::BIbcmp; else if (FnInfo->isStr("strncpy")) return Builtin::BIstrncpy; else if (FnInfo->isStr("strncmp")) Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -8426,6 +8426,7 @@ case Builtin::BIstrncmp: case Builtin::BIwcsncmp: case Builtin::BImemcmp: + case Builtin::BIbcmp: case Builtin::BIwmemcmp: // A call to strlen is not a constant expression. if (Info.getLangOpts().CPlusPlus11) @@ -8440,6 +8441,7 @@ case Builtin::BI__builtin_strncmp: case Builtin::BI__builtin_wcsncmp: case Builtin::BI__builtin_memcmp: + case Builtin::BI__builtin_bcmp: case Builtin::BI__builtin_wmemcmp: { LValue String1, String2; if (!EvaluatePointer(E->getArg(0), String1, Info) || @@ -8470,7 +8472,9 @@ QualType CharTy2 = String2.Designator.getType(Info.Ctx); bool IsRawByte = BuiltinOp == Builtin::BImemcmp || - BuiltinOp == Builtin::BI__builtin_memcmp; + BuiltinOp == Builtin::BIbcmp || + BuiltinOp == Builtin::BI__builtin_memcmp || + BuiltinOp == Builtin::BI__builtin_bcmp; assert(IsRawByte || (Info.Ctx.hasSameUnqualifiedType( @@ -8538,10 +8542,12 @@ return Success(0, E); } - bool StopAtNull = (BuiltinOp != Builtin::BImemcmp && - BuiltinOp != Builtin::BIwmemcmp && - BuiltinOp != Builtin::BI__builtin_memcmp && - BuiltinOp != Builtin::BI__builtin_wmemcmp); + bool StopAtNull = + (BuiltinOp != Builtin::BImemcmp && BuiltinOp != Builtin::BIbcmp && + BuiltinOp != Builtin::BIwmemcmp && + BuiltinOp != Builtin::BI__builtin_memcmp && + BuiltinOp != Builtin::BI__builtin_bcmp && + BuiltinOp != Builtin::BI__builtin_wmemcmp); bool IsWide = BuiltinOp == Builtin::BIwcscmp || BuiltinOp == Builtin::BIwcsncmp || BuiltinOp == Builtin::BIwmemcmp || Index: lib/Sema/SemaChecking.cpp =================================================================== --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -9174,23 +9174,23 @@ getContainedDynamicClass(PointeeTy, IsContained)) { unsigned OperationType = 0; + const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp; // "overwritten" if we're warning about the destination for any call // but memcmp; otherwise a verb appropriate to the call. - if (ArgIdx != 0 || BId == Builtin::BImemcmp) { + if (ArgIdx != 0 || IsCmp) { if (BId == Builtin::BImemcpy) OperationType = 1; else if(BId == Builtin::BImemmove) OperationType = 2; - else if (BId == Builtin::BImemcmp) + else if (IsCmp) OperationType = 3; } - DiagRuntimeBehavior( - Dest->getExprLoc(), Dest, - PDiag(diag::warn_dyn_class_memaccess) - << (BId == Builtin::BImemcmp ? ArgIdx + 2 : ArgIdx) - << FnName << IsContained << ContainedRD << OperationType - << Call->getCallee()->getSourceRange()); + DiagRuntimeBehavior(Dest->getExprLoc(), Dest, + PDiag(diag::warn_dyn_class_memaccess) + << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName + << IsContained << ContainedRD << OperationType + << Call->getCallee()->getSourceRange()); } else if (PointeeTy.hasNonTrivialObjCLifetime() && BId != Builtin::BImemset) DiagRuntimeBehavior(