]> granicus.if.org Git - clang/commitdiff
Add __builtin_object_size support.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 3 Sep 2008 21:13:56 +0000 (21:13 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 3 Sep 2008 21:13:56 +0000 (21:13 +0000)
 - Currently CodeGen always returns a conservative value for this (-1
   or 0 depending on the context).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55735 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Builtins.def
include/clang/Basic/DiagnosticKinds.def
lib/CodeGen/CGBuiltin.cpp
lib/Sema/Sema.h
lib/Sema/SemaChecking.cpp

index 589b5f69af867fcf60476545bec4c75d77a3748c..45e05d8392bf43d9d1a8ef353399600e6b3dda94 100644 (file)
@@ -124,6 +124,7 @@ BUILTIN(__builtin_memset, "v*v*cz", "n")
 BUILTIN(__builtin_return_address, "v*Ui", "n")
 BUILTIN(__builtin_frame_address, "v*Ui", "n")
 // GCC Object size checking builtins
+BUILTIN(__builtin_object_size, "zv*i", "n")
 BUILTIN(__builtin___memset_chk, "v*v*izz", "nF")
 BUILTIN(__builtin___memcpy_chk, "v*v*vC*zz", "nF")
 BUILTIN(__builtin___memmove_chk, "v*v*vC*zz", "nF")
index 473f51768183ca43427f2066a1ad10fe8c660d16..e6cc8ef772cab73b39d756468c7d4c9d4f805e16 100644 (file)
@@ -1197,7 +1197,10 @@ DIAG(err_stack_const_level, ERROR,
 
 DIAG(err_prefetch_invalid_argument, ERROR,
      "argument to __builtin_prefetch must be a constant integer")
-DIAG(err_prefetch_invalid_range, ERROR,
+DIAG(err_argument_invalid_range, ERROR,
      "argument should be a value from %0 to %1")
 
+DIAG(err_object_size_invalid_argument, ERROR,
+     "argument to __builtin_object_size must be a constant integer")
+
 #undef DIAG
index e89997afa1b36ec6509f88264d1ec07732362ca4..177e68e70496655ea777024211c10a238844efdb 100644 (file)
@@ -199,6 +199,16 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
     Value *F = CGM.getIntrinsic(Intrinsic::bswap, &ArgType, 1);
     return RValue::get(Builder.CreateCall(F, ArgValue, "tmp"));
   }    
+  case Builtin::BI__builtin_object_size: {
+    // FIXME: Implement. For now we just always fail and pretend we
+    // don't know the object size.
+    llvm::APSInt TypeArg = 
+      E->getArg(1)->getIntegerConstantExprValue(CGM.getContext());
+    const llvm::Type *ResType = ConvertType(E->getType());
+    //    bool UseSubObject = TypeArg.getZExtValue() & 1;
+    bool UseMinimum = TypeArg.getZExtValue() & 2;
+    return RValue::get(ConstantInt::get(ResType, UseMinimum ? 0 : -1LL));
+  }
   case Builtin::BI__builtin_prefetch: {
     Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
     // FIXME: Technically these constants should of type 'int', yes?
index faa16ca5e4610ccb7aa9f8ad4b1194595d950fdd..f048fd7a3a97115051702be9f1fefd6b88083e3e 100644 (file)
@@ -952,6 +952,7 @@ private:
   bool SemaBuiltinStackAddress(CallExpr *TheCall);
   Action::ExprResult SemaBuiltinShuffleVector(CallExpr *TheCall);
   bool SemaBuiltinPrefetch(CallExpr *TheCall); 
+  bool SemaBuiltinObjectSize(CallExpr *TheCall); 
   void CheckPrintfArguments(CallExpr *TheCall,
                             bool HasVAListArg, unsigned format_idx);
   void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
index e5e80db2befe82b25ef8695b325a9deec0c422f0..1c1c594edc4f5fb66774183af9a39beefe00aba4 100644 (file)
@@ -62,6 +62,9 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCallRaw) {
     if (SemaBuiltinPrefetch(TheCall.get()))
       return true;
     return TheCall.take();
+  case Builtin::BI__builtin_object_size:
+    if (SemaBuiltinObjectSize(TheCall.get()))
+      return true;
   }
   
   // Search the KnownFunctionIDs for the identifier.
@@ -300,8 +303,7 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
     QualType RWType = Arg->getType();
 
     const BuiltinType *BT = RWType->getAsBuiltinType();
-    // FIXME: 32 is wrong, needs to be proper width of Int
-    llvm::APSInt Result(32);
+    llvm::APSInt Result;
     if (!BT || BT->getKind() != BuiltinType::Int ||
         !Arg->isIntegerConstantExpr(Result, Context)) {
       if (Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_argument,
@@ -316,12 +318,12 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
     // is 3.
     if (i==1) {
       if (Result.getSExtValue() < 0 || Result.getSExtValue() > 1)
-        res |= Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_range,
+        res |= Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
                     "0", "1", 
                     SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
     } else {
       if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3)
-        res |= Diag(TheCall->getLocStart(), diag::err_prefetch_invalid_range,
+        res |= Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
                     "0", "3", 
                     SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
     }
@@ -330,6 +332,29 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) {
   return res;
 }
 
+/// SemaBuiltinObjectSize - Handle __builtin_object_size(void *ptr,
+/// int type). This simply type checks that type is one of the defined
+/// constants (0-3).
+bool Sema::SemaBuiltinObjectSize(CallExpr *TheCall) {
+  Expr *Arg = TheCall->getArg(1);
+  QualType ArgType = Arg->getType();  
+  const BuiltinType *BT = ArgType->getAsBuiltinType();  
+  llvm::APSInt Result(32);
+  if (!BT || BT->getKind() != BuiltinType::Int ||
+      !Arg->isIntegerConstantExpr(Result, Context)) {
+    return Diag(TheCall->getLocStart(), diag::err_object_size_invalid_argument,
+                SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
+  }
+
+  if (Result.getSExtValue() < 0 || Result.getSExtValue() > 3) {
+    return Diag(TheCall->getLocStart(), diag::err_argument_invalid_range,
+                "0", "3", 
+                SourceRange(Arg->getLocStart(), Arg->getLocEnd()));
+  }
+
+  return false;
+}
+
 /// CheckPrintfArguments - Check calls to printf (and similar functions) for
 /// correct use of format strings.  
 ///