Re: [PATCH] D12000: Bugfix - Clang handles __builtin_object_size in wrong way

2015-08-18 Thread George Burgess IV via cfe-commits
george.burgess.iv closed this revision.
george.burgess.iv added a comment.

r245323


http://reviews.llvm.org/D12000



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12000: Bugfix - Clang handles __builtin_object_size in wrong way

2015-08-17 Thread George Burgess IV via cfe-commits
george.burgess.iv added inline comments.


Comment at: lib/AST/ExprConstant.cpp:6221-6223
@@ +6220,5 @@
+  //
+  //   extern struct X { char buff[32]; int a, b, c; } *p;
+  //   int a = __builtin_object_size(p-buff + 4, 3); // returns 28
+  //   int b = __builtin_object_size(p-buff + 4, 2); // returns 0, not 40
+  //

rsmith wrote:
 Please add a testcase like this (where the base object is unknown but the 
 designator is known, and thus we can compute the Type == 1 and Type == 3 
 forms but not the Type == 0 and Type == 2 forms).
EvaluatePointer is stricter than I thought -- this is actually not possible 
without adding a decent amount of complexity to the current patch. Will replace 
the comment with a TODO, and add the test case in the next patch that makes us 
support things like this. :)


http://reviews.llvm.org/D12000



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12000: Bugfix - Clang handles __builtin_object_size in wrong way

2015-08-17 Thread George Burgess IV via cfe-commits
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 

Re: [PATCH] D12000: Bugfix - Clang handles __builtin_object_size in wrong way

2015-08-17 Thread Richard Smith via cfe-commits
rsmith accepted this revision.
rsmith added a reviewer: rsmith.
rsmith added a comment.
This revision is now accepted and ready to land.

LGTM with one more testcase :)



Comment at: lib/AST/ExprConstant.cpp:6243-6245
@@ +6242,5 @@
+  } else if (End.Designator.IsOnePastTheEnd) {
+// We're already pointing at the end of the object.
+AmountToAdd = 0;
+  }
+

rsmith wrote:
 Please add testcases for the pointer-to-the-end case:
 
   int n;
   static_assert(__builtin_object_size(n + 1, 1) == 0);
 
   struct X { int a, b, c; } x;
   static_assert(__builtin_object_size(x.a + 1, 1) == 0);
 
I think you now have a testcase for the end-of-array case, but not the 
end-of-nonarray case.


http://reviews.llvm.org/D12000



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D12000: Bugfix - Clang handles __builtin_object_size in wrong way

2015-08-14 Thread Richard Smith via cfe-commits
rsmith added a subscriber: rsmith.


Comment at: lib/AST/ExprConstant.cpp:6221-6223
@@ +6220,5 @@
+  //
+  //   extern struct X { char buff[32]; int a, b, c; } *p;
+  //   int a = __builtin_object_size(p-buff + 4, 3); // returns 28
+  //   int b = __builtin_object_size(p-buff + 4, 2); // returns 0, not 40
+  //

Please add a testcase like this (where the base object is unknown but the 
designator is known, and thus we can compute the Type == 1 and Type == 3 forms 
but not the Type == 0 and Type == 2 forms).


Comment at: lib/AST/ExprConstant.cpp:6243-6245
@@ +6242,5 @@
+  } else if (End.Designator.IsOnePastTheEnd) {
+// We're already pointing at the end of the object.
+AmountToAdd = 0;
+  }
+

Please add testcases for the pointer-to-the-end case:

  int n;
  static_assert(__builtin_object_size(n + 1, 1) == 0);

  struct X { int a, b, c; } x;
  static_assert(__builtin_object_size(x.a + 1, 1) == 0);



http://reviews.llvm.org/D12000



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits