static void SemaBuiltinMemChkCall(Sema &S, FunctionDecl *FDecl,
CallExpr *TheCall, unsigned SizeIdx,
- unsigned DstSizeIdx) {
+ unsigned DstSizeIdx,
+ StringRef LikelyMacroName) {
if (TheCall->getNumArgs() <= SizeIdx ||
TheCall->getNumArgs() <= DstSizeIdx)
return;
if (Size.ule(DstSize))
return;
- // confirmed overflow so generate the diagnostic.
- IdentifierInfo *FnName = FDecl->getIdentifier();
+ // Confirmed overflow, so generate the diagnostic.
+ StringRef FunctionName = FDecl->getName();
SourceLocation SL = TheCall->getBeginLoc();
- SourceRange SR = TheCall->getSourceRange();
+ SourceManager &SM = S.getSourceManager();
+ // If we're in an expansion of a macro whose name corresponds to this builtin,
+ // use the simple macro name and location.
+ if (SL.isMacroID() && Lexer::getImmediateMacroName(SL, SM, S.getLangOpts()) ==
+ LikelyMacroName) {
+ FunctionName = LikelyMacroName;
+ SL = SM.getImmediateMacroCallerLoc(SL);
+ }
- S.Diag(SL, diag::warn_memcpy_chk_overflow) << SR << FnName;
+ S.Diag(SL, diag::warn_memcpy_chk_overflow)
+ << FunctionName << DstSize.toString(/*Radix=*/10)
+ << Size.toString(/*Radix=*/10);
}
static bool SemaBuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall) {
// check secure string manipulation functions where overflows
// are detectable at compile time
case Builtin::BI__builtin___memcpy_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memcpy");
+ break;
case Builtin::BI__builtin___memmove_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memmove");
+ break;
case Builtin::BI__builtin___memset_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "memset");
+ break;
case Builtin::BI__builtin___strlcat_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strlcat");
+ break;
case Builtin::BI__builtin___strlcpy_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strlcpy");
+ break;
case Builtin::BI__builtin___strncat_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strncat");
+ break;
case Builtin::BI__builtin___strncpy_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "strncpy");
+ break;
case Builtin::BI__builtin___stpncpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3);
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 2, 3, "stpncpy");
break;
case Builtin::BI__builtin___memccpy_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 3, 4);
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 3, 4, "memccpy");
break;
case Builtin::BI__builtin___snprintf_chk:
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3, "snprintf");
+ break;
case Builtin::BI__builtin___vsnprintf_chk:
- SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3);
+ SemaBuiltinMemChkCall(*this, FDecl, TheCall, 1, 3, "vsnprintf");
break;
case Builtin::BI__builtin_call_with_static_chain:
if (SemaBuiltinCallWithStaticChain(*this, TheCall))
// rdar://6252231 - cannot call vsnprintf with va_list on x86_64
void f4(const char *fmt, ...) {
__builtin_va_list args;
- __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args); // expected-warning {{'__builtin___vsnprintf_chk' will always overflow destination buffer}}
+ __builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args); // expected-warning {{'__builtin___vsnprintf_chk' will always overflow; destination buffer has size 11, but size argument is 42}}
}
// rdar://18334276
char b[5];
char buf[10];
__builtin___memccpy_chk (buf, b, '\0', sizeof(b), __builtin_object_size (buf, 0));
- __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), __builtin_object_size (b, 0)); // expected-warning {{'__builtin___memccpy_chk' will always overflow destination buffer}}
+ __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), __builtin_object_size (b, 0)); // expected-warning {{'__builtin___memccpy_chk' will always overflow; destination buffer has size 5, but size argument is 10}}
}
int pr28314(void) {
// expected-note {{change size argument to be the size of the destination}}
__builtin___strlcpy_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcpy_chk' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcpy_chk' will always overflow destination buffer}}
+ // expected-warning {{'__builtin___strlcpy_chk' will always overflow; destination buffer has size 20, but size argument is 40}}
strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}}
__builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}} \
- // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}
+ // expected-warning {{'__builtin___strlcat_chk' will always overflow; destination buffer has size 20, but size argument is 40}}
}
// rdar://11076881
{
static char buf[10];
- __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
+ __builtin___memcpy_chk (&buf[6], in, 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow; destination buffer has size 4, but size argument is 5}}
__builtin___memcpy_chk (p, "abcde", n, __builtin_object_size (p, 0));
__builtin___memcpy_chk (&buf[5], "abcde", n, __builtin_object_size (&buf[5], 0));
- __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow destination buffer}}
+ __builtin___memcpy_chk (&buf[6], "abcde", 5, __builtin_object_size (&buf[6], 0)); // expected-warning {{'__builtin___memcpy_chk' will always overflow; destination buffer has size 4, but size argument is 5}}
return buf;
}
(void)__builtin_signbitl(1.0f);
(void)__builtin_signbitl(1.0L);
}
+
+// rdar://43909200
+#define memcpy(x,y,z) __builtin___memcpy_chk(x,y,z, __builtin_object_size(x,0))
+#define my_memcpy(x,y,z) __builtin___memcpy_chk(x,y,z, __builtin_object_size(x,0))
+
+void test23() {
+ char src[1024];
+ char buf[10];
+ memcpy(buf, src, 11); // expected-warning{{'memcpy' will always overflow; destination buffer has size 10, but size argument is 11}}
+ my_memcpy(buf, src, 11); // expected-warning{{'__builtin___memcpy_chk' will always overflow; destination buffer has size 10, but size argument is 11}}
+}