george.burgess.iv updated the summary for this revision.
george.burgess.iv updated this revision to Diff 32333.
george.burgess.iv marked an inline comment as done.
george.burgess.iv added a comment.
Addressed feedback.
http://reviews.llvm.org/D12000
Files:
lib/AST/ExprConstant.cpp
test/CodeGen/object-size.c
test/Sema/const-eval.c
Index: test/Sema/const-eval.c
===
--- test/Sema/const-eval.c
+++ test/Sema/const-eval.c
@@ -118,10 +118,6 @@
const float constfloat = 0;
EVAL_EXPR(43, varfloat constfloat) // expected-error {{must have a constant size}}
-// rdar://problem/11205586
-// (Make sure we continue to reject this.)
-EVAL_EXPR(44, x[0]); // expected-error {{variable length array}}
-
// rdar://problem/10962435
EVAL_EXPR(45, ((char*)-1) + 1 == 0 ? 1 : -1)
EVAL_EXPR(46, ((char*)-1) + 1 (char*) -1 ? 1 : -1)
Index: test/CodeGen/object-size.c
===
--- test/CodeGen/object-size.c
+++ test/CodeGen/object-size.c
@@ -146,3 +146,73 @@
// CHECK: call i64 @llvm.objectsize.i64
return __builtin_object_size(cond ? a : b, 0);
}
+
+// CHECK: @test19
+void test19() {
+ struct {
+int a, b;
+ } foo;
+
+ // CHECK: store i32 8
+ gi = __builtin_object_size(foo.a, 0);
+ // CHECK: store i32 4
+ gi = __builtin_object_size(foo.a, 1);
+ // CHECK: store i32 8
+ gi = __builtin_object_size(foo.a, 2);
+ // CHECK: store i32 4
+ gi = __builtin_object_size(foo.a, 3);
+}
+
+// CHECK: @test20
+void test20() {
+ struct { int t[10]; } t[10];
+
+ // CHECK: store i32 380
+ gi = __builtin_object_size(t[0].t[5], 0);
+ // CHECK: store i32 20
+ gi = __builtin_object_size(t[0].t[5], 1);
+ // CHECK: store i32 380
+ gi = __builtin_object_size(t[0].t[5], 2);
+ // CHECK: store i32 20
+ gi = __builtin_object_size(t[0].t[5], 3);
+}
+
+// CHECK: @test21
+void test21() {
+ struct { int t[10]; } t[10];
+
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[10], 0);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[10], 1);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[10], 2);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[10], 3);
+
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[9].t[10], 0);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[9].t[10], 1);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[9].t[10], 2);
+ // CHECK: store i32 0
+ gi = __builtin_object_size(t[9].t[10], 3);
+}
+
+struct Test22Ty { int t[10]; };
+
+// CHECK: @test22
+void test22(struct Test22Ty *p) {
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
+ gi = __builtin_object_size(p, 0);
+ // CHECK: call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 false)
+ gi = __builtin_object_size(p, 1);
+ // CHECK:= call i64 @llvm.objectsize.i64.p0i8(i8* %{{.*}}, i1 true)
+ gi = __builtin_object_size(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);
+}
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -967,10 +967,6 @@
// Check this LValue refers to an object. If not, set the designator to be
// invalid and emit a diagnostic.
bool checkSubobject(EvalInfo Info, const Expr *E, CheckSubobjectKind CSK) {
- // Outside C++11, do not build a designator referring to a subobject of
- // any object: we won't use such a designator for anything.
- if (!Info.getLangOpts().CPlusPlus11)
-Designator.setInvalid();
return (CSK == CSK_ArrayToPointer || checkNullPointer(Info, E, CSK))
Designator.checkSubobject(Info, E, CSK);
}
@@ -2713,8 +2709,7 @@
// Check for special cases where there is no existing APValue to look at.
const Expr *Base = LVal.Base.dyn_castconst Expr*();
- if (!LVal.Designator.Invalid Base !LVal.CallIndex
- !Type.isVolatileQualified()) {
+ if (Base !LVal.CallIndex !Type.isVolatileQualified()) {
if (const CompoundLiteralExpr *CLE = dyn_castCompoundLiteralExpr(Base)) {
// In C99, a CompoundLiteralExpr is an lvalue, and we defer evaluating the
// initializer until now for such expressions. Such an expression can't be
@@ -5998,8 +5993,7 @@
bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
private:
- static QualType GetObjectType(APValue::LValueBase B);
- bool TryEvaluateBuiltinObjectSize(const CallExpr *E);
+ bool TryEvaluateBuiltinObjectSize(const CallExpr *E, unsigned Type);
// FIXME: Missing: array subscript of vector, member of vector
};
} // end anonymous namespace
@@ -6171,7 +6165,7 @@
/// Retrieves the underlying object type of the given expression,
/// as used by __builtin_object_size.
-QualType IntExprEvaluator::GetObjectType(APValue::LValueBase B) {
+static QualType