From: Fariborz Jahanian Date: Mon, 22 Sep 2014 17:11:59 +0000 (+0000) Subject: Fix evatuated value of __builtin_object_size according to its X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b6d4ef4fac0f5d3c4b987370d72864449d03628d;p=clang Fix evatuated value of __builtin_object_size according to its '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 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 743e59f19a..0bd45dac64 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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() || diff --git a/test/Sema/builtin-object-size.c b/test/Sema/builtin-object-size.c index db4832e347..b878c65017 100644 --- a/test/Sema/builtin-object-size.c +++ b/test/Sema/builtin-object-size.c @@ -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}} +}