return false;
}
- // If we can prove the base is null, lower to zero now.
- if (!Base.getLValueBase()) return Success(0, E);
+ if (!Base.getLValueBase()) {
+ // It is not possible to determine which objects ptr points to at compile time,
+ // __builtin_object_size should return (size_t) -1 for type 0 or 1
+ // and (size_t) 0 for type 2 or 3.
+ llvm::APSInt TypeIntVaue;
+ const Expr *ExprType = E->getArg(1);
+ if (!ExprType->EvaluateAsInt(TypeIntVaue, Info.Ctx))
+ return false;
+ if (TypeIntVaue == 0 || TypeIntVaue == 1)
+ return Success(-1, E);
+ if (TypeIntVaue == 2 || TypeIntVaue == 3)
+ return Success(0, E);
+ return Error(E);
+ }
QualType T = GetObjectType(Base.getLValueBase());
if (T.isNull() ||
__builtin___vsnprintf_chk (0, 42, 0, 11, fmt, args); // expected-warning {{'__builtin___vsnprintf_chk' will always overflow destination buffer}}
}
+// rdar://18334276
+typedef unsigned long size_t;
+void * memcset(void *restrict dst, int src, size_t n);
+void * memcpy(void *restrict dst, const void *restrict src, size_t n);
+
+#define memset(dest, src, len) __builtin___memset_chk(dest, src, len, __builtin_object_size(dest, 0))
+#define memcpy(dest, src, len) __builtin___memcpy_chk(dest, src, len, __builtin_object_size(dest, 0))
+#define memcpy1(dest, src, len) __builtin___memcpy_chk(dest, src, len, __builtin_object_size(dest, 4))
+#define NULL ((void *)0)
+
+void f5(void)
+{
+ char buf[10];
+ memset((void *)0x100000000ULL, 0, 0x1000);
+ memcpy((char *)NULL + 0x10000, buf, 0x10);
+ memcpy1((char *)NULL + 0x10000, buf, 0x10); // expected-error {{argument should be a value from 0 to 3}}
+}