]> granicus.if.org Git - clang/commitdiff
Add a new builtin: __builtin_dynamic_object_size
authorErik Pilkington <erik.pilkington@gmail.com>
Wed, 30 Jan 2019 20:34:53 +0000 (20:34 +0000)
committerErik Pilkington <erik.pilkington@gmail.com>
Wed, 30 Jan 2019 20:34:53 +0000 (20:34 +0000)
This builtin has the same UI as __builtin_object_size, but has the
potential to be evaluated dynamically. It is meant to be used as a
drop-in replacement for libraries that use __builtin_object_size when
a dynamic checking mode is enabled. For instance,
__builtin_object_size fails to provide any extra checking in the
following function:

  void f(size_t alloc) {
    char* p = malloc(alloc);
    strcpy(p, "foobar"); // expands to __builtin___strcpy_chk(p, "foobar", __builtin_object_size(p, 0))
  }

This is an overflow if alloc < 7, but because LLVM can't fold the
object size intrinsic statically, it folds __builtin_object_size to
-1. With __builtin_dynamic_object_size, alloc is passed through to
__builtin___strcpy_chk.

rdar://32212419

Differential revision: https://reviews.llvm.org/D56760

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

12 files changed:
docs/LanguageExtensions.rst
include/clang/Basic/Builtins.def
lib/AST/ExprConstant.cpp
lib/Analysis/CFG.cpp
lib/CodeGen/CGBuiltin.cpp
lib/CodeGen/CGCall.cpp
lib/CodeGen/CodeGenFunction.h
lib/Sema/SemaChecking.cpp
lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
test/CodeGen/alloc-size.c
test/CodeGen/object-size.c
test/Sema/builtin-object-size.c

index 03b20c26c309fb56f4ca6649c81e18cc58186cb5..d4c40b29f80efffebefb31e1992535e879403cb9 100644 (file)
@@ -2922,3 +2922,29 @@ Specifying Linker Options on ELF Targets
 The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
 The second parameter is the library name (without the traditional Unix prefix of
 ``lib``).  This allows you to provide an implicit link of dependent libraries.
+
+Evaluating Object Size Dynamically
+==================================
+
+Clang supports the builtin ``__builtin_dynamic_object_size``, the semantics are
+the same as GCC's ``__builtin_object_size`` (which Clang also supports), but
+``__builtin_dynamic_object_size`` can evaluate the object's size at runtime.
+``__builtin_dynamic_object_size`` is meant to be used as a drop-in replacement
+for ``__builtin_object_size`` in libraries that support it.
+
+For instance, here is a program that ``__builtin_dynamic_object_size`` will make
+safer:
+
+.. code-block:: c
+
+  void copy_into_buffer(size_t size) {
+    char* buffer = malloc(size);
+    strlcpy(buffer, "some string", strlen("some string"));
+    // Previous line preprocesses to:
+    // __builtin___strlcpy_chk(buffer, "some string", strlen("some string"), __builtin_object_size(buffer, 0))
+  }
+
+Since the size of ``buffer`` can't be known at compile time, Clang will fold
+``__builtin_object_size(buffer, 0)`` into ``-1``. However, if this was written
+as ``__builtin_dynamic_object_size(buffer, 0)``, Clang will fold it into
+``size``, providing some extra runtime safety.
index 4efd8437959cb3924394dcf12b2d4f3de77f7d96..2e8c6d971211ec49c90e54270d52148f27d92784 100644 (file)
@@ -511,6 +511,7 @@ BUILTIN(__builtin_extend_pointer, "ULLiv*", "n") // _Unwind_Word == uint64_t
 
 // GCC Object size checking builtins
 BUILTIN(__builtin_object_size, "zvC*i", "nu")
+BUILTIN(__builtin_dynamic_object_size, "zvC*i", "nu") // Clang only.
 BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
 BUILTIN(__builtin___memccpy_chk, "v*v*vC*izz", "nF")
 BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
index 62845a45c3a8553aa2cc9802a2442b4551dbfc60..8f20e12a516331fdbb8f23ebf2fb8b23127940bc 100644 (file)
@@ -8190,6 +8190,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
   default:
     return ExprEvaluatorBaseTy::VisitCallExpr(E);
 
+  case Builtin::BI__builtin_dynamic_object_size:
   case Builtin::BI__builtin_object_size: {
     // The type was checked when we built the expression.
     unsigned Type =
index 0a62ed2c03675891a30b2b8a16a3908d34b21069..f6b829147b343ac4c950395e74a9bb6dcb3162ec 100644 (file)
@@ -2458,7 +2458,8 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
       NoReturn = true;
     if (FD->hasAttr<NoThrowAttr>())
       AddEHEdge = false;
-    if (FD->getBuiltinID() == Builtin::BI__builtin_object_size)
+    if (FD->getBuiltinID() == Builtin::BI__builtin_object_size ||
+        FD->getBuiltinID() == Builtin::BI__builtin_dynamic_object_size)
       OmitArguments = true;
   }
 
index f1014b61831178c7942d249e929502edf679cdbc..93b577502da5ad3e57352a598fb6289a0f7ea4ec 100644 (file)
@@ -494,10 +494,11 @@ getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
 llvm::Value *
 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
                                                  llvm::IntegerType *ResType,
-                                                 llvm::Value *EmittedE) {
+                                                 llvm::Value *EmittedE,
+                                                 bool IsDynamic) {
   uint64_t ObjectSize;
   if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
-    return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
+    return emitBuiltinObjectSize(E, Type, ResType, EmittedE, IsDynamic);
   return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
 }
 
@@ -513,7 +514,7 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
 llvm::Value *
 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
                                        llvm::IntegerType *ResType,
-                                       llvm::Value *EmittedE) {
+                                       llvm::Value *EmittedE, bool IsDynamic) {
   // We need to reference an argument if the pointer is a parameter with the
   // pass_object_size attribute.
   if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
@@ -549,7 +550,7 @@ CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
   Value *Min = Builder.getInt1((Type & 2) != 0);
   // For GCC compatibility, __builtin_object_size treat NULL as unknown size.
   Value *NullIsUnknown = Builder.getTrue();
-  Value *Dynamic = Builder.getFalse();
+  Value *Dynamic = Builder.getInt1(IsDynamic);
   return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic});
 }
 
@@ -1978,6 +1979,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
       Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/false);
     return RValue::get(Result);
   }
+  case Builtin::BI__builtin_dynamic_object_size:
   case Builtin::BI__builtin_object_size: {
     unsigned Type =
         E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
@@ -1985,8 +1987,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
 
     // We pass this builtin onto the optimizer so that it can figure out the
     // object size in more complex cases.
+    bool IsDynamic = BuiltinID == Builtin::BI__builtin_dynamic_object_size;
     return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
-                                             /*EmittedE=*/nullptr));
+                                             /*EmittedE=*/nullptr, IsDynamic));
   }
   case Builtin::BI__builtin_prefetch: {
     Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
index 829821a156dcfcd3e50f3206b5fe8863664877b1..893a6f2f902d6221293f667b961d71b79fb49baf 100644 (file)
@@ -3459,7 +3459,8 @@ void CodeGenFunction::EmitCallArgs(
     auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
     assert(EmittedArg.getScalarVal() && "We emitted nothing for the arg?");
     llvm::Value *V = evaluateOrEmitBuiltinObjectSize(Arg, PS->getType(), T,
-                                                     EmittedArg.getScalarVal());
+                                                     EmittedArg.getScalarVal(),
+                                                     /*IsDynamic=*/false);
     Args.add(RValue::get(V), SizeTy);
     // If we're emitting args in reverse, be sure to do so with
     // pass_object_size, as well.
index 87d141fe6f0a8f703fbaabba1309f79c51e0eade..a989a0e46cad6d1fef7d35d1b9421b3c05251e89 100644 (file)
@@ -4177,14 +4177,16 @@ private:
   /// If EmittedExpr is non-null, this will use that instead of re-emitting E.
   llvm::Value *evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
                                                llvm::IntegerType *ResType,
-                                               llvm::Value *EmittedE);
+                                               llvm::Value *EmittedE,
+                                               bool IsDynamic);
 
   /// Emits the size of E, as required by __builtin_object_size. This
   /// function is aware of pass_object_size parameters, and will act accordingly
   /// if E is a parameter with the pass_object_size attribute.
   llvm::Value *emitBuiltinObjectSize(const Expr *E, unsigned Type,
                                      llvm::IntegerType *ResType,
-                                     llvm::Value *EmittedE);
+                                     llvm::Value *EmittedE,
+                                     bool IsDynamic);
 
 public:
 #ifndef NDEBUG
index 5a5e5616e801aa9625aeff98db245ce9f16d1791..4b5c68a7bde8cc65b5da7ef2c0e703e456972bfc 100644 (file)
@@ -1076,6 +1076,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
     if (SemaBuiltinAssumeAligned(TheCall))
       return ExprError();
     break;
+  case Builtin::BI__builtin_dynamic_object_size:
   case Builtin::BI__builtin_object_size:
     if (SemaBuiltinConstantArgRange(TheCall, 1, 0, 3))
       return ExprError();
index f35ee0fb612df2b05a1e14f3fa17d20ba1aae4dc..290a03517920e260e7d2c9ef1c0f1a085542a5f8 100644 (file)
@@ -95,6 +95,7 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
     return true;
   }
 
+  case Builtin::BI__builtin_dynamic_object_size:
   case Builtin::BI__builtin_object_size:
   case Builtin::BI__builtin_constant_p: {
     // This must be resolvable at compile time, so we defer to the constant
index 7953d02923b52944ee170d9faac836b5a465753a..aa5b295b0c30709bd6ad68199fb3933a990fe5a9 100644 (file)
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1           -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+#ifdef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#endif
 
 #define NULL ((void *)0)
 
@@ -20,86 +27,86 @@ void *my_calloc(size_t, size_t) __attribute__((alloc_size(1, 2)));
 void test1() {
   void *const vp = my_malloc(100);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 0);
+  gi = OBJECT_SIZE_BUILTIN(vp, 0);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 1);
+  gi = OBJECT_SIZE_BUILTIN(vp, 1);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 2);
+  gi = OBJECT_SIZE_BUILTIN(vp, 2);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 3);
+  gi = OBJECT_SIZE_BUILTIN(vp, 3);
 
   void *const arr = my_calloc(100, 5);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr, 0);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr, 1);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr, 2);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr, 3);
 
   // CHECK: store i32 100
-  gi = __builtin_object_size(my_malloc(100), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 0);
   // CHECK: store i32 100
-  gi = __builtin_object_size(my_malloc(100), 1);
+  gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 1);
   // CHECK: store i32 100
-  gi = __builtin_object_size(my_malloc(100), 2);
+  gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 2);
   // CHECK: store i32 100
-  gi = __builtin_object_size(my_malloc(100), 3);
+  gi = OBJECT_SIZE_BUILTIN(my_malloc(100), 3);
 
   // CHECK: store i32 500
-  gi = __builtin_object_size(my_calloc(100, 5), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 0);
   // CHECK: store i32 500
-  gi = __builtin_object_size(my_calloc(100, 5), 1);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 1);
   // CHECK: store i32 500
-  gi = __builtin_object_size(my_calloc(100, 5), 2);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 2);
   // CHECK: store i32 500
-  gi = __builtin_object_size(my_calloc(100, 5), 3);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(100, 5), 3);
 
   void *const zeroPtr = my_malloc(0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(zeroPtr, 0);
+  gi = OBJECT_SIZE_BUILTIN(zeroPtr, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(my_malloc(0), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_malloc(0), 0);
 
   void *const zeroArr1 = my_calloc(0, 1);
   void *const zeroArr2 = my_calloc(1, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(zeroArr1, 0);
+  gi = OBJECT_SIZE_BUILTIN(zeroArr1, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(zeroArr2, 0);
+  gi = OBJECT_SIZE_BUILTIN(zeroArr2, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(my_calloc(1, 0), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(1, 0), 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(my_calloc(0, 1), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_calloc(0, 1), 0);
 }
 
 // CHECK-LABEL: @test2
 void test2() {
   void *const vp = my_malloc(gi);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(vp, 0);
+  gi = OBJECT_SIZE_BUILTIN(vp, 0);
 
   void *const arr1 = my_calloc(gi, 1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr1, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr1, 0);
 
   void *const arr2 = my_calloc(1, gi);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr2, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr2, 0);
 }
 
 // CHECK-LABEL: @test3
 void test3() {
   char *const buf = (char *)my_calloc(100, 5);
   // CHECK: store i32 500
-  gi = __builtin_object_size(buf, 0);
+  gi = OBJECT_SIZE_BUILTIN(buf, 0);
   // CHECK: store i32 500
-  gi = __builtin_object_size(buf, 1);
+  gi = OBJECT_SIZE_BUILTIN(buf, 1);
   // CHECK: store i32 500
-  gi = __builtin_object_size(buf, 2);
+  gi = OBJECT_SIZE_BUILTIN(buf, 2);
   // CHECK: store i32 500
-  gi = __builtin_object_size(buf, 3);
+  gi = OBJECT_SIZE_BUILTIN(buf, 3);
 }
 
 struct Data {
@@ -113,41 +120,41 @@ struct Data {
 void test5() {
   struct Data *const data = my_malloc(sizeof(*data));
   // CHECK: store i32 48
-  gi = __builtin_object_size(data, 0);
+  gi = OBJECT_SIZE_BUILTIN(data, 0);
   // CHECK: store i32 48
-  gi = __builtin_object_size(data, 1);
+  gi = OBJECT_SIZE_BUILTIN(data, 1);
   // CHECK: store i32 48
-  gi = __builtin_object_size(data, 2);
+  gi = OBJECT_SIZE_BUILTIN(data, 2);
   // CHECK: store i32 48
-  gi = __builtin_object_size(data, 3);
+  gi = OBJECT_SIZE_BUILTIN(data, 3);
 
   // CHECK: store i32 40
-  gi = __builtin_object_size(&data->t[1], 0);
+  gi = OBJECT_SIZE_BUILTIN(&data->t[1], 0);
   // CHECK: store i32 36
-  gi = __builtin_object_size(&data->t[1], 1);
+  gi = OBJECT_SIZE_BUILTIN(&data->t[1], 1);
   // CHECK: store i32 40
-  gi = __builtin_object_size(&data->t[1], 2);
+  gi = OBJECT_SIZE_BUILTIN(&data->t[1], 2);
   // CHECK: store i32 36
-  gi = __builtin_object_size(&data->t[1], 3);
+  gi = OBJECT_SIZE_BUILTIN(&data->t[1], 3);
 
   struct Data *const arr = my_calloc(sizeof(*data), 2);
   // CHECK: store i32 96
-  gi = __builtin_object_size(arr, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr, 0);
   // CHECK: store i32 96
-  gi = __builtin_object_size(arr, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr, 1);
   // CHECK: store i32 96
-  gi = __builtin_object_size(arr, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr, 2);
   // CHECK: store i32 96
-  gi = __builtin_object_size(arr, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr, 3);
 
   // CHECK: store i32 88
-  gi = __builtin_object_size(&arr->t[1], 0);
+  gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 0);
   // CHECK: store i32 36
-  gi = __builtin_object_size(&arr->t[1], 1);
+  gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 1);
   // CHECK: store i32 88
-  gi = __builtin_object_size(&arr->t[1], 2);
+  gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 2);
   // CHECK: store i32 36
-  gi = __builtin_object_size(&arr->t[1], 3);
+  gi = OBJECT_SIZE_BUILTIN(&arr->t[1], 3);
 }
 
 // CHECK-LABEL: @test6
@@ -156,13 +163,13 @@ void test6() {
   // so when we know the source of the allocation.
   struct Data *const data = my_malloc(sizeof(*data) + 10);
   // CHECK: store i32 11
-  gi = __builtin_object_size(data->end, 0);
+  gi = OBJECT_SIZE_BUILTIN(data->end, 0);
   // CHECK: store i32 11
-  gi = __builtin_object_size(data->end, 1);
+  gi = OBJECT_SIZE_BUILTIN(data->end, 1);
   // CHECK: store i32 11
-  gi = __builtin_object_size(data->end, 2);
+  gi = OBJECT_SIZE_BUILTIN(data->end, 2);
   // CHECK: store i32 11
-  gi = __builtin_object_size(data->end, 3);
+  gi = OBJECT_SIZE_BUILTIN(data->end, 3);
 
   struct Data *const arr = my_calloc(sizeof(*arr) + 5, 3);
   // AFAICT, GCC treats malloc and calloc identically. So, we should do the
@@ -178,67 +185,67 @@ void test6() {
   // or "allocate M smaller `Data`s with extra padding".
 
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr->end, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr->end, 0);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr->end, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr->end, 1);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr->end, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr->end, 2);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr->end, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr->end, 3);
 
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr[0].end, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr[0].end, 0);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr[0].end, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr[0].end, 1);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr[0].end, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr[0].end, 2);
   // CHECK: store i32 112
-  gi = __builtin_object_size(arr[0].end, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr[0].end, 3);
 
   // CHECK: store i32 64
-  gi = __builtin_object_size(arr[1].end, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr[1].end, 0);
   // CHECK: store i32 64
-  gi = __builtin_object_size(arr[1].end, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr[1].end, 1);
   // CHECK: store i32 64
-  gi = __builtin_object_size(arr[1].end, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr[1].end, 2);
   // CHECK: store i32 64
-  gi = __builtin_object_size(arr[1].end, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr[1].end, 3);
 
   // CHECK: store i32 16
-  gi = __builtin_object_size(arr[2].end, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr[2].end, 0);
   // CHECK: store i32 16
-  gi = __builtin_object_size(arr[2].end, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr[2].end, 1);
   // CHECK: store i32 16
-  gi = __builtin_object_size(arr[2].end, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr[2].end, 2);
   // CHECK: store i32 16
-  gi = __builtin_object_size(arr[2].end, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr[2].end, 3);
 }
 
 // CHECK-LABEL: @test7
 void test7() {
   struct Data *const data = my_malloc(sizeof(*data) + 5);
   // CHECK: store i32 9
-  gi = __builtin_object_size(data->pad, 0);
+  gi = OBJECT_SIZE_BUILTIN(data->pad, 0);
   // CHECK: store i32 3
-  gi = __builtin_object_size(data->pad, 1);
+  gi = OBJECT_SIZE_BUILTIN(data->pad, 1);
   // CHECK: store i32 9
-  gi = __builtin_object_size(data->pad, 2);
+  gi = OBJECT_SIZE_BUILTIN(data->pad, 2);
   // CHECK: store i32 3
-  gi = __builtin_object_size(data->pad, 3);
+  gi = OBJECT_SIZE_BUILTIN(data->pad, 3);
 }
 
 // CHECK-LABEL: @test8
 void test8() {
   // Non-const pointers aren't currently supported.
   void *buf = my_calloc(100, 5);
-  // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
-  gi = __builtin_object_size(buf, 0);
+  // CHECK: @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
+  gi = OBJECT_SIZE_BUILTIN(buf, 0);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(buf, 1);
+  gi = OBJECT_SIZE_BUILTIN(buf, 1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(buf, 2);
+  gi = OBJECT_SIZE_BUILTIN(buf, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(buf, 3);
+  gi = OBJECT_SIZE_BUILTIN(buf, 3);
 }
 
 // CHECK-LABEL: @test9
@@ -249,11 +256,11 @@ void test9() {
   short *const buf2 = ((short*)(my_malloc(100)));
 
   // CHECK: store i32 100
-  gi = __builtin_object_size(buf0, 0);
+  gi = OBJECT_SIZE_BUILTIN(buf0, 0);
   // CHECK: store i32 100
-  gi = __builtin_object_size(buf1, 0);
+  gi = OBJECT_SIZE_BUILTIN(buf1, 0);
   // CHECK: store i32 100
-  gi = __builtin_object_size(buf2, 0);
+  gi = OBJECT_SIZE_BUILTIN(buf2, 0);
 }
 
 // CHECK-LABEL: @test10
@@ -261,36 +268,36 @@ void test10() {
   // Yay overflow
   short *const arr = my_calloc((size_t)-1 / 2 + 1, 2);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr, 0);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr, 1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(arr, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr, 3);
 
   // As an implementation detail, CharUnits can't handle numbers greater than or
   // equal to 2**63. Realistically, this shouldn't be a problem, but we should
   // be sure we don't emit crazy results for this case.
   short *const buf = my_malloc((size_t)-1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(buf, 0);
+  gi = OBJECT_SIZE_BUILTIN(buf, 0);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(buf, 1);
+  gi = OBJECT_SIZE_BUILTIN(buf, 1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(buf, 2);
+  gi = OBJECT_SIZE_BUILTIN(buf, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(buf, 3);
+  gi = OBJECT_SIZE_BUILTIN(buf, 3);
 
   short *const arr_big = my_calloc((size_t)-1 / 2 - 1, 2);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr_big, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr_big, 0);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr_big, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr_big, 1);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr_big, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr_big, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(arr_big, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr_big, 3);
 }
 
 void *my_tiny_malloc(char) __attribute__((alloc_size(1)));
@@ -300,25 +307,25 @@ void *my_tiny_calloc(char, char) __attribute__((alloc_size(1, 2)));
 void test11() {
   void *const vp = my_tiny_malloc(100);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 0);
+  gi = OBJECT_SIZE_BUILTIN(vp, 0);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 1);
+  gi = OBJECT_SIZE_BUILTIN(vp, 1);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 2);
+  gi = OBJECT_SIZE_BUILTIN(vp, 2);
   // CHECK: store i32 100
-  gi = __builtin_object_size(vp, 3);
+  gi = OBJECT_SIZE_BUILTIN(vp, 3);
 
   // N.B. This causes char overflow, but not size_t overflow, so it should be
   // supported.
   void *const arr = my_tiny_calloc(100, 5);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr, 0);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 1);
+  gi = OBJECT_SIZE_BUILTIN(arr, 1);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 2);
+  gi = OBJECT_SIZE_BUILTIN(arr, 2);
   // CHECK: store i32 500
-  gi = __builtin_object_size(arr, 3);
+  gi = OBJECT_SIZE_BUILTIN(arr, 3);
 }
 
 void *my_signed_malloc(long) __attribute__((alloc_size(1)));
@@ -327,26 +334,26 @@ void *my_signed_calloc(long, long) __attribute__((alloc_size(1, 2)));
 // CHECK-LABEL: @test12
 void test12() {
   // CHECK: store i32 100
-  gi = __builtin_object_size(my_signed_malloc(100), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(100), 0);
   // CHECK: store i32 500
-  gi = __builtin_object_size(my_signed_calloc(100, 5), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(100, 5), 0);
 
   void *const vp = my_signed_malloc(-2);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(vp, 0);
+  gi = OBJECT_SIZE_BUILTIN(vp, 0);
   // N.B. These get lowered to -1 because the function calls may have
   // side-effects, and we can't determine the objectsize.
   // CHECK: store i32 -1
-  gi = __builtin_object_size(my_signed_malloc(-2), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_signed_malloc(-2), 0);
 
   void *const arr1 = my_signed_calloc(-2, 1);
   void *const arr2 = my_signed_calloc(1, -2);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr1, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr1, 0);
   // CHECK: @llvm.objectsize
-  gi = __builtin_object_size(arr2, 0);
+  gi = OBJECT_SIZE_BUILTIN(arr2, 0);
   // CHECK: store i32 -1
-  gi = __builtin_object_size(my_signed_calloc(1, -2), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(1, -2), 0);
   // CHECK: store i32 -1
-  gi = __builtin_object_size(my_signed_calloc(-2, 1), 0);
+  gi = OBJECT_SIZE_BUILTIN(my_signed_calloc(-2, 1), 0);
 }
index 9014e04cc52651de0f1da8311ffd96a91b5297d6..561fd4d9119b372b5d9f2cbac441afd4e6a2e0e4 100644 (file)
@@ -1,12 +1,19 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1           -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -DDYNAMIC -triple x86_64-apple-darwin -emit-llvm %s -o - 2>&1 | FileCheck %s
+
+#ifndef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#endif
 
 #define strcpy(dest, src) \
-  ((__builtin_object_size(dest, 0) != -1ULL) \
-   ? __builtin___strcpy_chk (dest, src, __builtin_object_size(dest, 1)) \
+  ((OBJECT_SIZE_BUILTIN(dest, 0) != -1ULL) \
+   ? __builtin___strcpy_chk (dest, src, OBJECT_SIZE_BUILTIN(dest, 1)) \
    : __inline_strcpy_chk(dest, src))
 
 static char *__inline_strcpy_chk (char *dest, const char *src) {
-  return __builtin___strcpy_chk(dest, src, __builtin_object_size(dest, 1));
+  return __builtin___strcpy_chk(dest, src, OBJECT_SIZE_BUILTIN(dest, 1));
 }
 
 char gbuf[63];
@@ -40,7 +47,7 @@ void test4() {
 // CHECK-LABEL: define void @test5
 void test5() {
   // CHECK:     = load i8*, i8** @gp
-  // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1 false)
+  // CHECK-NEXT:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
   strcpy(gp, "Hi there");
 }
 
@@ -130,13 +137,13 @@ void test16() {
 // CHECK-LABEL: @test17
 void test17() {
   // CHECK: store i32 -1
-  gi = __builtin_object_size(gp++, 0);
+  gi = OBJECT_SIZE_BUILTIN(gp++, 0);
   // CHECK: store i32 -1
-  gi = __builtin_object_size(gp++, 1);
+  gi = OBJECT_SIZE_BUILTIN(gp++, 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size(gp++, 2);
+  gi = OBJECT_SIZE_BUILTIN(gp++, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(gp++, 3);
+  gi = OBJECT_SIZE_BUILTIN(gp++, 3);
 }
 
 // CHECK-LABEL: @test18
@@ -144,7 +151,7 @@ unsigned test18(int cond) {
   int a[4], b[4];
   // CHECK: phi i32*
   // CHECK: call i64 @llvm.objectsize.i64
-  return __builtin_object_size(cond ? a : b, 0);
+  return OBJECT_SIZE_BUILTIN(cond ? a : b, 0);
 }
 
 // CHECK-LABEL: @test19
@@ -154,22 +161,22 @@ void test19() {
   } foo;
 
   // CHECK: store i32 8
-  gi = __builtin_object_size(&foo.a, 0);
+  gi = OBJECT_SIZE_BUILTIN(&foo.a, 0);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.a, 1);
+  gi = OBJECT_SIZE_BUILTIN(&foo.a, 1);
   // CHECK: store i32 8
-  gi = __builtin_object_size(&foo.a, 2);
+  gi = OBJECT_SIZE_BUILTIN(&foo.a, 2);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.a, 3);
+  gi = OBJECT_SIZE_BUILTIN(&foo.a, 3);
 
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.b, 0);
+  gi = OBJECT_SIZE_BUILTIN(&foo.b, 0);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.b, 1);
+  gi = OBJECT_SIZE_BUILTIN(&foo.b, 1);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.b, 2);
+  gi = OBJECT_SIZE_BUILTIN(&foo.b, 2);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&foo.b, 3);
+  gi = OBJECT_SIZE_BUILTIN(&foo.b, 3);
 }
 
 // CHECK-LABEL: @test20
@@ -177,13 +184,13 @@ void test20() {
   struct { int t[10]; } t[10];
 
   // CHECK: store i32 380
-  gi = __builtin_object_size(&t[0].t[5], 0);
+  gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 0);
   // CHECK: store i32 20
-  gi = __builtin_object_size(&t[0].t[5], 1);
+  gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 1);
   // CHECK: store i32 380
-  gi = __builtin_object_size(&t[0].t[5], 2);
+  gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 2);
   // CHECK: store i32 20
-  gi = __builtin_object_size(&t[0].t[5], 3);
+  gi = OBJECT_SIZE_BUILTIN(&t[0].t[5], 3);
 }
 
 // CHECK-LABEL: @test21
@@ -191,22 +198,22 @@ void test21() {
   struct { int t; } t;
 
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t + 1, 0);
+  gi = OBJECT_SIZE_BUILTIN(&t + 1, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t + 1, 1);
+  gi = OBJECT_SIZE_BUILTIN(&t + 1, 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t + 1, 2);
+  gi = OBJECT_SIZE_BUILTIN(&t + 1, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t + 1, 3);
+  gi = OBJECT_SIZE_BUILTIN(&t + 1, 3);
 
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t.t + 1, 0);
+  gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t.t + 1, 1);
+  gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t.t + 1, 2);
+  gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t.t + 1, 3);
+  gi = OBJECT_SIZE_BUILTIN(&t.t + 1, 3);
 }
 
 // CHECK-LABEL: @test22
@@ -214,40 +221,40 @@ void test22() {
   struct { int t[10]; } t[10];
 
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[10], 0);
+  gi = OBJECT_SIZE_BUILTIN(&t[10], 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[10], 1);
+  gi = OBJECT_SIZE_BUILTIN(&t[10], 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[10], 2);
+  gi = OBJECT_SIZE_BUILTIN(&t[10], 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[10], 3);
+  gi = OBJECT_SIZE_BUILTIN(&t[10], 3);
 
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[9].t[10], 0);
+  gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[9].t[10], 1);
+  gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[9].t[10], 2);
+  gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[9].t[10], 3);
+  gi = OBJECT_SIZE_BUILTIN(&t[9].t[10], 3);
 
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[0] + sizeof(t), 0);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[0] + sizeof(t), 1);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[0] + sizeof(t), 2);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[0] + sizeof(t), 3);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[0] + sizeof(t), 3);
 
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 0);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 1);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
+  gi = OBJECT_SIZE_BUILTIN((char*)&t[9].t[0] + 10*sizeof(t[0].t), 3);
 }
 
 struct Test23Ty { int a; int t[10]; };
@@ -255,73 +262,73 @@ struct Test23Ty { int a; int t[10]; };
 // CHECK-LABEL: @test23
 void test23(struct Test23Ty *p) {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(p, 0);
+  gi = OBJECT_SIZE_BUILTIN(p, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(p, 1);
+  gi = OBJECT_SIZE_BUILTIN(p, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(p, 2);
+  gi = OBJECT_SIZE_BUILTIN(p, 2);
   // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
   // data to correctly handle type=3
   // CHECK: store i32 0
-  gi = __builtin_object_size(p, 3);
+  gi = OBJECT_SIZE_BUILTIN(p, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&p->a, 0);
+  gi = OBJECT_SIZE_BUILTIN(&p->a, 0);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&p->a, 1);
+  gi = OBJECT_SIZE_BUILTIN(&p->a, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(&p->a, 2);
+  gi = OBJECT_SIZE_BUILTIN(&p->a, 2);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&p->a, 3);
+  gi = OBJECT_SIZE_BUILTIN(&p->a, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&p->t[5], 0);
+  gi = OBJECT_SIZE_BUILTIN(&p->t[5], 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&p->t[5], 1);
+  gi = OBJECT_SIZE_BUILTIN(&p->t[5], 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(&p->t[5], 2);
+  gi = OBJECT_SIZE_BUILTIN(&p->t[5], 2);
   // CHECK: store i32 20
-  gi = __builtin_object_size(&p->t[5], 3);
+  gi = OBJECT_SIZE_BUILTIN(&p->t[5], 3);
 }
 
-// PR24493 -- ICE if __builtin_object_size called with NULL and (Type & 1) != 0
+// PR24493 -- ICE if OBJECT_SIZE_BUILTIN called with NULL and (Type & 1) != 0
 // CHECK-LABEL: @test24
 void test24() {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0, 0);
+  gi = OBJECT_SIZE_BUILTIN((void*)0, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0, 1);
+  gi = OBJECT_SIZE_BUILTIN((void*)0, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size((void*)0, 2);
+  gi = OBJECT_SIZE_BUILTIN((void*)0, 2);
   // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
   // Hopefully will be lowered properly in the future.
   // CHECK: store i32 0
-  gi = __builtin_object_size((void*)0, 3);
+  gi = OBJECT_SIZE_BUILTIN((void*)0, 3);
 }
 
 // CHECK-LABEL: @test25
 void test25() {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0x1000, 0);
+  gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0x1000, 1);
+  gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size((void*)0x1000, 2);
+  gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 2);
   // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
   // Hopefully will be lowered properly in the future.
   // CHECK: store i32 0
-  gi = __builtin_object_size((void*)0x1000, 3);
+  gi = OBJECT_SIZE_BUILTIN((void*)0x1000, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0 + 0x1000, 0);
+  gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size((void*)0 + 0x1000, 1);
+  gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size((void*)0 + 0x1000, 2);
+  gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 2);
   // Note: Currently fixed at zero because LLVM can't handle type=3 correctly.
   // Hopefully will be lowered properly in the future.
   // CHECK: store i32 0
-  gi = __builtin_object_size((void*)0 + 0x1000, 3);
+  gi = OBJECT_SIZE_BUILTIN((void*)0 + 0x1000, 3);
 }
 
 // CHECK-LABEL: @test26
@@ -329,13 +336,13 @@ void test26() {
   struct { int v[10]; } t[10];
 
   // CHECK: store i32 316
-  gi = __builtin_object_size(&t[1].v[11], 0);
+  gi = OBJECT_SIZE_BUILTIN(&t[1].v[11], 0);
   // CHECK: store i32 312
-  gi = __builtin_object_size(&t[1].v[12], 1);
+  gi = OBJECT_SIZE_BUILTIN(&t[1].v[12], 1);
   // CHECK: store i32 308
-  gi = __builtin_object_size(&t[1].v[13], 2);
+  gi = OBJECT_SIZE_BUILTIN(&t[1].v[13], 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(&t[1].v[14], 3);
+  gi = OBJECT_SIZE_BUILTIN(&t[1].v[14], 3);
 }
 
 struct Test27IncompleteTy;
@@ -343,29 +350,29 @@ struct Test27IncompleteTy;
 // CHECK-LABEL: @test27
 void test27(struct Test27IncompleteTy *t) {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(t, 0);
+  gi = OBJECT_SIZE_BUILTIN(t, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(t, 1);
+  gi = OBJECT_SIZE_BUILTIN(t, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(t, 2);
+  gi = OBJECT_SIZE_BUILTIN(t, 2);
   // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
   // data to correctly handle type=3
   // CHECK: store i32 0
-  gi = __builtin_object_size(t, 3);
+  gi = OBJECT_SIZE_BUILTIN(t, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&test27, 0);
+  gi = OBJECT_SIZE_BUILTIN(&test27, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&test27, 1);
+  gi = OBJECT_SIZE_BUILTIN(&test27, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(&test27, 2);
+  gi = OBJECT_SIZE_BUILTIN(&test27, 2);
   // Note: this is currently fixed at 0 because LLVM doesn't have sufficient
   // data to correctly handle type=3
   // CHECK: store i32 0
-  gi = __builtin_object_size(&test27, 3);
+  gi = OBJECT_SIZE_BUILTIN(&test27, 3);
 }
 
-// The intent of this test is to ensure that __builtin_object_size treats `&foo`
+// The intent of this test is to ensure that OBJECT_SIZE_BUILTIN treats `&foo`
 // and `(T*)&foo` identically, when used as the pointer argument.
 // CHECK-LABEL: @test28
 void test28() {
@@ -373,22 +380,22 @@ void test28() {
 
 #define addCasts(s) ((char*)((short*)(s)))
   // CHECK: store i32 360
-  gi = __builtin_object_size(addCasts(&t[1]), 0);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 0);
   // CHECK: store i32 360
-  gi = __builtin_object_size(addCasts(&t[1]), 1);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 1);
   // CHECK: store i32 360
-  gi = __builtin_object_size(addCasts(&t[1]), 2);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 2);
   // CHECK: store i32 360
-  gi = __builtin_object_size(addCasts(&t[1]), 3);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1]), 3);
 
   // CHECK: store i32 356
-  gi = __builtin_object_size(addCasts(&t[1].v[1]), 0);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 0);
   // CHECK: store i32 36
-  gi = __builtin_object_size(addCasts(&t[1].v[1]), 1);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 1);
   // CHECK: store i32 356
-  gi = __builtin_object_size(addCasts(&t[1].v[1]), 2);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 2);
   // CHECK: store i32 36
-  gi = __builtin_object_size(addCasts(&t[1].v[1]), 3);
+  gi = OBJECT_SIZE_BUILTIN(addCasts(&t[1].v[1]), 3);
 #undef addCasts
 }
 
@@ -416,40 +423,40 @@ struct StaticStruct {
 void test29(struct DynStructVar *dv, struct DynStruct0 *d0,
             struct DynStruct1 *d1, struct StaticStruct *ss) {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(dv->snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(dv->snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(dv->snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(dv->snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(dv->snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(dv->snd, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(dv->snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(dv->snd, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(d0->snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(d0->snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(d0->snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(d0->snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(d0->snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(d0->snd, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(d0->snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(d0->snd, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(d1->snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(d1->snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(d1->snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(d1->snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(d1->snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(d1->snd, 2);
   // CHECK: store i32 1
-  gi = __builtin_object_size(d1->snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(d1->snd, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(ss->snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(ss->snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(ss->snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(ss->snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(ss->snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(ss->snd, 2);
   // CHECK: store i32 2
-  gi = __builtin_object_size(ss->snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(ss->snd, 3);
 }
 
 // CHECK-LABEL: @test30
@@ -457,41 +464,41 @@ void test30() {
   struct { struct DynStruct1 fst, snd; } *nested;
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(nested->fst.snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 0);
   // CHECK: store i32 1
-  gi = __builtin_object_size(nested->fst.snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(nested->fst.snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 2);
   // CHECK: store i32 1
-  gi = __builtin_object_size(nested->fst.snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(nested->fst.snd, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(nested->snd.snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(nested->snd.snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(nested->snd.snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 2);
   // CHECK: store i32 1
-  gi = __builtin_object_size(nested->snd.snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(nested->snd.snd, 3);
 
   union { struct DynStruct1 d1; char c[1]; } *u;
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(u->c, 0);
+  gi = OBJECT_SIZE_BUILTIN(u->c, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(u->c, 1);
+  gi = OBJECT_SIZE_BUILTIN(u->c, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(u->c, 2);
+  gi = OBJECT_SIZE_BUILTIN(u->c, 2);
   // CHECK: store i32 1
-  gi = __builtin_object_size(u->c, 3);
+  gi = OBJECT_SIZE_BUILTIN(u->c, 3);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(u->d1.snd, 0);
+  gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(u->d1.snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(u->d1.snd, 2);
+  gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 2);
   // CHECK: store i32 1
-  gi = __builtin_object_size(u->d1.snd, 3);
+  gi = OBJECT_SIZE_BUILTIN(u->d1.snd, 3);
 }
 
 // CHECK-LABEL: @test31
@@ -503,19 +510,19 @@ void test31() {
   struct StaticStruct *ss;
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(ds1[9].snd, 1);
+  gi = OBJECT_SIZE_BUILTIN(ds1[9].snd, 1);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&ss[9].snd[0], 1);
+  gi = OBJECT_SIZE_BUILTIN(&ss[9].snd[0], 1);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&ds1[9].snd[0], 1);
+  gi = OBJECT_SIZE_BUILTIN(&ds1[9].snd[0], 1);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&ds0[9].snd[0], 1);
+  gi = OBJECT_SIZE_BUILTIN(&ds0[9].snd[0], 1);
 
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(&dsv[9].snd[0], 1);
+  gi = OBJECT_SIZE_BUILTIN(&dsv[9].snd[0], 1);
 }
 
 // CHECK-LABEL: @PR30346
@@ -528,26 +535,26 @@ void PR30346() {
 
   struct sockaddr *sa;
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(sa->sa_data, 0);
+  gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false, i1 true, i1
-  gi = __builtin_object_size(sa->sa_data, 1);
+  gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true, i1 true, i1
-  gi = __builtin_object_size(sa->sa_data, 2);
+  gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 2);
   // CHECK: store i32 14
-  gi = __builtin_object_size(sa->sa_data, 3);
+  gi = OBJECT_SIZE_BUILTIN(sa->sa_data, 3);
 }
 
 extern char incomplete_char_array[];
 // CHECK-LABEL: @incomplete_and_function_types
 int incomplete_and_function_types() {
   // CHECK: call i64 @llvm.objectsize.i64.p0i8
-  gi = __builtin_object_size(incomplete_char_array, 0);
+  gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 0);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8
-  gi = __builtin_object_size(incomplete_char_array, 1);
+  gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 1);
   // CHECK: call i64 @llvm.objectsize.i64.p0i8
-  gi = __builtin_object_size(incomplete_char_array, 2);
+  gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 2);
   // CHECK: store i32 0
-  gi = __builtin_object_size(incomplete_char_array, 3);
+  gi = OBJECT_SIZE_BUILTIN(incomplete_char_array, 3);
 }
 
 // Flips between the pointer and lvalue evaluator a lot.
@@ -564,7 +571,7 @@ void deeply_nested() {
   } *a;
 
   // CHECK: store i32 4
-  gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 1);
+  gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 1);
   // CHECK: store i32 4
-  gi = __builtin_object_size(&a->b[1].c[1].d[1].e[1], 3);
+  gi = OBJECT_SIZE_BUILTIN(&a->b[1].c[1].d[1].e[1], 3);
 }
index fcf86f3e344a70cdc1b3e352b307bc6bdc2b9061..ff8707493ab84c897e138dfe76d5ba4c3e98f042 100644 (file)
@@ -1,22 +1,29 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+// RUN: %clang_cc1 -DDYNAMIC -fsyntax-only -triple x86_64-apple-darwin9 -verify %s
+
+#ifndef DYNAMIC
+#define OBJECT_SIZE_BUILTIN __builtin_object_size
+#else
+#define OBJECT_SIZE_BUILTIN __builtin_dynamic_object_size
+#endif
 
 int a[10];
 
 int f0() {
-  return __builtin_object_size(&a); // expected-error {{too few arguments to function}}
+  return OBJECT_SIZE_BUILTIN(&a); // expected-error {{too few arguments to function}}
 }
 int f1() {
-  return (__builtin_object_size(&a, 0) + 
-          __builtin_object_size(&a, 1) + 
-          __builtin_object_size(&a, 2) + 
-          __builtin_object_size(&a, 3));
+  return (OBJECT_SIZE_BUILTIN(&a, 0) + 
+          OBJECT_SIZE_BUILTIN(&a, 1) + 
+          OBJECT_SIZE_BUILTIN(&a, 2) + 
+          OBJECT_SIZE_BUILTIN(&a, 3));
 }
 int f2() {
-  return __builtin_object_size(&a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
+  return OBJECT_SIZE_BUILTIN(&a, -1); // expected-error {{argument value -1 is outside the valid range [0, 3]}}
 }
 int f3() {
-  return __builtin_object_size(&a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
+  return OBJECT_SIZE_BUILTIN(&a, 4); // expected-error {{argument value 4 is outside the valid range [0, 3]}}
 }
 
 
@@ -31,9 +38,9 @@ typedef __typeof__(sizeof(int)) 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 memset(dest, src, len) __builtin___memset_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 0))
+#define memcpy(dest, src, len) __builtin___memcpy_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 0))
+#define memcpy1(dest, src, len) __builtin___memcpy_chk(dest, src, len, OBJECT_SIZE_BUILTIN(dest, 4))
 #define NULL ((void *)0)
 
 void f5(void)
@@ -49,8 +56,8 @@ void f6(void)
 {
   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 has size 5, but size argument is 10}}
+  __builtin___memccpy_chk (buf, b, '\0', sizeof(b), OBJECT_SIZE_BUILTIN (buf, 0));
+  __builtin___memccpy_chk (b, buf, '\0', sizeof(buf), OBJECT_SIZE_BUILTIN (b, 0));  // expected-warning {{'__builtin___memccpy_chk' will always overflow; destination buffer has size 5, but size argument is 10}}
 }
 
 int pr28314(void) {
@@ -70,10 +77,10 @@ int pr28314(void) {
   } *p3;
 
   int a = 0;
-  a += __builtin_object_size(&p->a, 0);
-  a += __builtin_object_size(p->b, 0);
-  a += __builtin_object_size(p2->b, 0);
-  a += __builtin_object_size(p3->b, 0);
+  a += OBJECT_SIZE_BUILTIN(&p->a, 0);
+  a += OBJECT_SIZE_BUILTIN(p->b, 0);
+  a += OBJECT_SIZE_BUILTIN(p2->b, 0);
+  a += OBJECT_SIZE_BUILTIN(p3->b, 0);
   return a;
 }
 
@@ -82,12 +89,12 @@ int pr31843() {
 
   struct { int f; } a;
   int b;
-  n += __builtin_object_size(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
+  n += OBJECT_SIZE_BUILTIN(({&(b ? &a : &a)->f; pr31843;}), 0); // expected-warning{{expression result unused}}
 
   struct statfs { char f_mntonname[1024];};
   struct statfs *outStatFSBuf;
-  n += __builtin_object_size(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
-  n += __builtin_object_size(outStatFSBuf->f_mntonname ?: "", 1);
+  n += OBJECT_SIZE_BUILTIN(outStatFSBuf->f_mntonname ? "" : "", 1); // expected-warning{{address of array}}
+  n += OBJECT_SIZE_BUILTIN(outStatFSBuf->f_mntonname ?: "", 1);
 
   return n;
 }
@@ -104,7 +111,7 @@ typedef struct {
 void rd36094951_IAS_builtin_object_size_assertion(IncompleteArrayStruct *p) {
 #define rd36094951_CHECK(mode)                                                 \
   __builtin___strlcpy_chk(p->session[0].string, "ab", 2,                       \
-                          __builtin_object_size(p->session[0].string, mode))
+                          OBJECT_SIZE_BUILTIN(p->session[0].string, mode))
   rd36094951_CHECK(0);
   rd36094951_CHECK(1);
   rd36094951_CHECK(2);