@@ -44,7 +44,8 @@ KType *CXXTypeManager::getWrappedType(llvm::Type *type) {
4444      /*  Vector types are considered as their elements type */ 
4545      llvm::Type *unwrappedRawType = type;
4646      if  (unwrappedRawType->isVectorTy ()) {
47-         unwrappedRawType = llvm::cast<llvm::VectorType>(unwrappedRawType)->getElementType ();
47+         unwrappedRawType =
48+             llvm::cast<llvm::VectorType>(unwrappedRawType)->getElementType ();
4849      }
4950
5051      switch  (unwrappedRawType->getTypeID ()) {
@@ -54,6 +55,10 @@ KType *CXXTypeManager::getWrappedType(llvm::Type *type) {
5455      case  (llvm::Type::IntegerTyID):
5556        kt = new  cxxtypes::KCXXIntegerType (unwrappedRawType, this );
5657        break ;
58+       case  (llvm::Type::PPC_FP128TyID):
59+       case  (llvm::Type::FP128TyID):
60+       case  (llvm::Type::X86_FP80TyID):
61+       case  (llvm::Type::DoubleTyID):
5762      case  (llvm::Type::FloatTyID):
5863        kt = new  cxxtypes::KCXXFloatingPointType (unwrappedRawType, this );
5964        break ;
@@ -193,6 +198,19 @@ bool cxxtypes::KCXXType::isAccessableFrom(KType *accessingType) const {
193198  assert (false  && " Attempted to compare raw llvm type with C++ type!" 
194199}
195200
201+ ref<Expr> cxxtypes::KCXXType::getContentRestrictions (ref<Expr> object) const  {
202+   if  (type == nullptr ) {
203+     return  nullptr ;
204+   }
205+   llvm::Type *elementType = type->getPointerElementType ();
206+   return  llvm::cast<cxxtypes::KCXXType>(parent->getWrappedType (elementType))
207+       ->getPointersRestrictions (object);
208+ }
209+ 
210+ ref<Expr> cxxtypes::KCXXType::getPointersRestrictions (ref<Expr>) const  {
211+   return  nullptr ;
212+ }
213+ 
196214bool  cxxtypes::KCXXType::isAccessingFromChar (KCXXType *accessingType) {
197215  /*  Special case for unknown type */ 
198216  if  (accessingType->getRawType () == nullptr ) {
@@ -231,6 +249,35 @@ cxxtypes::KCXXCompositeType::KCXXCompositeType(KType *type, TypeManager *parent,
231249  insertedTypes.emplace (type);
232250}
233251
252+ ref<Expr>
253+ cxxtypes::KCXXCompositeType::getPointersRestrictions (ref<Expr> object) const  {
254+   if  (containsSymbolic) {
255+     return  nullptr ;
256+   }
257+ 
258+   ref<Expr> result = nullptr ;
259+   for  (auto  &offsetToType : typesLocations) {
260+     size_t  offset = offsetToType.first ;
261+     KType *extractedType = offsetToType.second .first ;
262+ 
263+     ref<Expr> extractedOffset = ExtractExpr::create (
264+         object, offset * CHAR_BIT, extractedType->getSize () * CHAR_BIT);
265+     ref<Expr> innerAlignmentRequirement =
266+         llvm::cast<KCXXType>(extractedType)
267+             ->getPointersRestrictions (extractedOffset);
268+     if  (innerAlignmentRequirement.isNull ()) {
269+       continue ;
270+     }
271+ 
272+     if  (result.isNull ()) {
273+       result = innerAlignmentRequirement;
274+     } else  {
275+       result = AndExpr::create (result, innerAlignmentRequirement);
276+     }
277+   }
278+   return  result;
279+ }
280+ 
234281void  cxxtypes::KCXXCompositeType::handleMemoryAccess (KType *type,
235282                                                     ref<Expr> offset,
236283                                                     ref<Expr> size,
@@ -411,6 +458,35 @@ cxxtypes::KCXXStructType::KCXXStructType(llvm::Type *type, TypeManager *parent)
411458  }
412459}
413460
461+ ref<Expr>
462+ cxxtypes::KCXXStructType::getPointersRestrictions (ref<Expr> object) const  {
463+   ref<Expr> result = nullptr ;
464+   for  (auto  &innerTypeToOffsets : innerTypes) {
465+     KType *innerType = innerTypeToOffsets.first ;
466+     if  (!llvm::isa<KCXXPointerType>(innerType)) {
467+       continue ;
468+     }
469+     for  (auto  offset : innerTypeToOffsets.second ) {
470+       ref<Expr> extractedExpr = ExtractExpr::create (
471+           object, offset * CHAR_BIT, innerType->getSize () * CHAR_BIT);
472+ 
473+       ref<Expr> innerAlignmentRequirement =
474+           llvm::cast<KCXXType>(innerType)->getPointersRestrictions (
475+               extractedExpr);
476+       if  (innerAlignmentRequirement.isNull ()) {
477+         continue ;
478+       }
479+ 
480+       if  (result.isNull ()) {
481+         result = innerAlignmentRequirement;
482+       } else  {
483+         result = AndExpr::create (result, innerAlignmentRequirement);
484+       }
485+     }
486+   }
487+   return  result;
488+ }
489+ 
414490bool  cxxtypes::KCXXStructType::isAccessableFrom (KCXXType *accessingType) const  {
415491  /*  FIXME: this is a temporary hack for vtables in C++. Ideally, we
416492   * should demangle global variables to get additional info, at least 
@@ -460,6 +536,28 @@ cxxtypes::KCXXArrayType::KCXXArrayType(llvm::Type *type, TypeManager *parent)
460536  arrayElementsCount = rawArrayType->getArrayNumElements ();
461537}
462538
539+ ref<Expr>
540+ cxxtypes::KCXXArrayType::getPointersRestrictions (ref<Expr> object) const  {
541+   ref<Expr> result = nullptr ;
542+   for  (unsigned  idx = 0 ; idx < arrayElementsCount; ++idx) {
543+     ref<Expr> extractedExpr =
544+         ExtractExpr::create (object, idx * elementType->getSize () * CHAR_BIT,
545+                             elementType->getSize () * CHAR_BIT);
546+     ref<Expr> innerAlignmentRequirement =
547+         elementType->getPointersRestrictions (extractedExpr);
548+     if  (innerAlignmentRequirement.isNull ()) {
549+       continue ;
550+     }
551+ 
552+     if  (result.isNull ()) {
553+       result = innerAlignmentRequirement;
554+     } else  {
555+       result = AndExpr::create (result, innerAlignmentRequirement);
556+     }
557+   }
558+   return  result;
559+ }
560+ 
463561bool  cxxtypes::KCXXArrayType::isAccessableFrom (KCXXType *accessingType) const  {
464562  if  (llvm::isa<KCXXArrayType>(accessingType)) {
465563    return  innerIsAccessableFrom (llvm::cast<KCXXArrayType>(accessingType));
@@ -575,6 +673,26 @@ bool cxxtypes::KCXXPointerType::innerIsAccessableFrom(
575673  return  accessingType->getRawType () == nullptr ;
576674}
577675
676+ ref<Expr>
677+ cxxtypes::KCXXPointerType::getPointersRestrictions (ref<Expr> object) const  {
678+   /* *
679+    * We assume that alignment is always a power of 2 and has 
680+    * a bit representation as 00...010...00. By subtracting 1 
681+    * we are getting 00...011...1. Then we apply this mask to 
682+    * address and require, that bitwise AND should give 0 (i.e. 
683+    * non of the last bits is 1). 
684+    */  
685+   ref<Expr> appliedAlignmentMask = AndExpr::create (
686+       Expr::createPointer (elementType->getAlignment () - 1 ), object);
687+ 
688+   ref<Expr> sizeExpr = Expr::createPointer (elementType->getSize () - 1 );
689+ 
690+   ref<Expr> objectUpperBound = AddExpr::create (object, sizeExpr);
691+ 
692+   return  AndExpr::create (Expr::createIsZero (appliedAlignmentMask),
693+                          UgeExpr::create (objectUpperBound, sizeExpr));
694+ }
695+ 
578696bool  cxxtypes::KCXXPointerType::innerIsAccessableFrom (
579697    KCXXPointerType *accessingType) const  {
580698  return  elementType->isAccessableFrom (accessingType->elementType );
0 commit comments