E = E->IgnoreParens();
// If we're doing a variable assignment from e.g. malloc(N), there will
- // probably be a cast of some kind. Ignore it.
+ // probably be a cast of some kind. In exotic cases, we might also see a
+ // top-level ExprWithCleanups. Ignore them either way.
+ if (const auto *EC = dyn_cast<ExprWithCleanups>(E))
+ E = EC->getSubExpr()->IgnoreParens();
+
if (const auto *Cast = dyn_cast<CastExpr>(E))
E = Cast->getSubExpr()->IgnoreParens();
// CHECK: ret i32 32
return __builtin_object_size(C().my_calloc(16, 2), 0);
}
+
+struct D {
+ ~D();
+ void *my_malloc(int N) __attribute__((alloc_size(2)));
+};
+
+// CHECK-LABEL: define i32 @_Z20callExprWithCleanupsv
+int callExprWithCleanups() {
+ int *const p = (int *)D().my_malloc(3);
+ // CHECK: ret i32 3
+ return __builtin_object_size(p, 0);
+}