]> granicus.if.org Git - clang/commitdiff
Fix evatuated value of __builtin_object_size according to its
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Sep 2014 17:11:59 +0000 (17:11 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 22 Sep 2014 17:11:59 +0000 (17:11 +0000)
'type'  argument when it cannot be determined which objects ptr
points to at compile time. rdar://18334276

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218258 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/builtin-object-size.c

index 743e59f19a62c6b4d17164929cbf6f6761be50db..0bd45dac644d8aaddbc473390d1f733b049db91f 100644 (file)
@@ -6052,8 +6052,20 @@ bool IntExprEvaluator::TryEvaluateBuiltinObjectSize(const CallExpr *E) {
       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() ||
index db4832e347a08943365731734faa75b8507fc6ed..b878c65017c0f0167a3b945f5545e5efd94c5d92 100644 (file)
@@ -26,3 +26,20 @@ void f4(const char *fmt, ...) {
  __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}}
+}