]> granicus.if.org Git - clang/commitdiff
__builtin_object_size refinements. Also handle stack based objects. WIP.
authorMike Stump <mrs@apple.com>
Mon, 26 Oct 2009 23:05:19 +0000 (23:05 +0000)
committerMike Stump <mrs@apple.com>
Mon, 26 Oct 2009 23:05:19 +0000 (23:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85174 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
lib/AST/ExprConstant.cpp
test/CodeGen/object-size.c

index d63e01dcd0d28555d1a2293ed4a2f733b09a4384..bcac18ffa22b4185522fadda6806fdd3319c5730 100644 (file)
@@ -241,6 +241,10 @@ public:
   /// in Result.
   bool Evaluate(EvalResult &Result, ASTContext &Ctx) const;
 
+  /// EvaluateAsAny - The same as Evaluate, except that it also succeeds on
+  /// stack based objects.
+  bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const;
+
   /// isEvaluatable - Call Evaluate to see if this expression can be constant
   /// folded, but discard the result.
   bool isEvaluatable(ASTContext &Ctx) const;
index 9992b6944ec35b58bc9e9c5b5b9d4c4ad5e4b451..8435e03417308dde245c1874a6b3ac2b88b2f5c0 100644 (file)
@@ -877,7 +877,7 @@ bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
   case Builtin::BI__builtin_object_size: {
     const Expr *Arg = E->getArg(0)->IgnoreParens();
     Expr::EvalResult Base;
-    if (Arg->Evaluate(Base, Info.Ctx)
+    if (Arg->EvaluateAsAny(Base, Info.Ctx)
         && Base.Val.getKind() == APValue::LValue
         && !Base.HasSideEffects)
       if (const Expr *LVBase = Base.Val.getLValueBase())
@@ -1830,6 +1830,33 @@ bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
   return true;
 }
 
+bool Expr::EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const {
+  EvalInfo Info(Ctx, Result, true);
+
+  if (getType()->isVectorType()) {
+    if (!EvaluateVector(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isIntegerType()) {
+    if (!IntExprEvaluator(Info, Result.Val).Visit(const_cast<Expr*>(this)))
+      return false;
+  } else if (getType()->hasPointerRepresentation()) {
+    if (!EvaluatePointer(this, Result.Val, Info))
+      return false;
+  } else if (getType()->isRealFloatingType()) {
+    llvm::APFloat f(0.0);
+    if (!EvaluateFloat(this, f, Info))
+      return false;
+
+    Result.Val = APValue(f);
+  } else if (getType()->isAnyComplexType()) {
+    if (!EvaluateComplex(this, Result.Val, Info))
+      return false;
+  } else
+    return false;
+
+  return true;
+}
+
 bool Expr::EvaluateAsLValue(EvalResult &Result, ASTContext &Ctx) const {
   EvalInfo Info(Ctx, Result);
 
index 36dc341e932785301d6c8337e86bb32e54cbf51e..970d11f6e1650bdac59ef4a19cf7dc3f8876f346 100644 (file)
@@ -47,3 +47,13 @@ void test6() {
   // CHECK:       call    ___inline_strcpy_chk
   strcpy((++i, gbuf), "Hi there");
 }
+
+void test7() {
+  char buf[57];
+
+  // CHECK:       movabsq $53, %rdx
+  // CHECK-NEXT:  movq    %rax, %rdi
+  // CHECK-NEXT:  movq    %rcx, %rsi
+  // CHECK-NEXT:  call    ___strcpy_chk
+  strcpy(&buf[4], "Hi there");
+}