r246890 - Fix a bug in __builtin_object_size cast removal

George Burgess IV via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 4 15:36:19 PDT 2015


Author: gbiv
Date: Fri Sep  4 17:36:18 2015
New Revision: 246890

URL: http://llvm.org/viewvc/llvm-project?rev=246890&view=rev
Log:
Fix a bug in __builtin_object_size cast removal

Apparently there are many cast kinds that may cause implicit pointer
arithmetic to happen. In light of this, the cast ignoring logic
introduced in r246877 has been changed to only ignore a small set of
cast kinds, and a test for this behavior has been added.

Thanks to Richard for catching this before it became a bug report. :)


Added:
    cfe/trunk/test/CodeGen/object-size.cpp
Modified:
    cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=246890&r1=246889&r2=246890&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Sep  4 17:36:18 2015
@@ -6249,8 +6249,8 @@ static QualType getObjectType(APValue::L
 }
 
 /// A more selective version of E->IgnoreParenCasts for
-/// TryEvaluateBuiltinObjectSize. This ignores casts/parens that serve only to
-/// change the type of E.
+/// TryEvaluateBuiltinObjectSize. This ignores some casts/parens that serve only
+/// to change the type of E.
 /// Ex. For E = `(short*)((char*)(&foo))`, returns `&foo`
 ///
 /// Always returns an RValue with a pointer representation.
@@ -6259,7 +6259,14 @@ static const Expr *ignorePointerCastsAnd
 
   auto *NoParens = E->IgnoreParens();
   auto *Cast = dyn_cast<CastExpr>(NoParens);
-  if (Cast == nullptr || Cast->getCastKind() == CK_DerivedToBase)
+  if (Cast == nullptr)
+    return NoParens;
+
+  // We only conservatively allow a few kinds of casts, because this code is
+  // inherently a simple solution that seeks to support the common case.
+  auto CastKind = Cast->getCastKind();
+  if (CastKind != CK_NoOp && CastKind != CK_BitCast &&
+      CastKind != CK_AddressSpaceConversion)
     return NoParens;
 
   auto *SubExpr = Cast->getSubExpr();

Added: cfe/trunk/test/CodeGen/object-size.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/object-size.cpp?rev=246890&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/object-size.cpp (added)
+++ cfe/trunk/test/CodeGen/object-size.cpp Fri Sep  4 17:36:18 2015
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s
+
+// C++-specific tests for __builtin_object_size
+
+int gi;
+
+// CHECK-LABEL: define void @_Z5test1v()
+void test1() {
+  // Guaranteeing that our cast removal logic doesn't break more interesting
+  // cases.
+  struct A { int a; };
+  struct B { int b; };
+  struct C: public A, public B {};
+
+  C c;
+
+  // CHECK: store i32 8
+  gi = __builtin_object_size(&c, 0);
+  // CHECK: store i32 8
+  gi = __builtin_object_size((A*)&c, 0);
+  // CHECK: store i32 4
+  gi = __builtin_object_size((B*)&c, 0);
+
+  // CHECK: store i32 8
+  gi = __builtin_object_size((char*)&c, 0);
+  // CHECK: store i32 8
+  gi = __builtin_object_size((char*)(A*)&c, 0);
+  // CHECK: store i32 4
+  gi = __builtin_object_size((char*)(B*)&c, 0);
+}




More information about the cfe-commits mailing list