bool CXXConstructorDecl::isCopyConstructorLikeSpecialization() const { if ((getNumParams() < 1) || (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || (getPrimaryTemplate() == 0) || (getDescribedFunctionTemplate() != 0)) return false; const ParmVarDecl *Param = getParamDecl(0); ASTContext &Context = getASTContext(); CanQualType ParamType = Context.getCanonicalType(Param->getType()); // Strip off the lvalue reference, if any. if (CanQual<LValueReferenceType> ParamRefType = ParamType->getAs<LValueReferenceType>()) ParamType = ParamRefType->getPointeeType(); // Is it the same as our our class type? CanQualType ClassTy = Context.getCanonicalType(Context.getTagDeclType(getParent())); if (ParamType.getUnqualifiedType() != ClassTy) return false; return true; }
llvm::Value * CodeGenFunction::EmitCXXTypeidExpr(const CXXTypeidExpr *E) { QualType Ty = E->getType(); const llvm::Type *LTy = ConvertType(Ty)->getPointerTo(); if (E->isTypeOperand()) { Ty = E->getTypeOperand(); CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); Ty = CanTy.getUnqualifiedType().getNonReferenceType(); if (const RecordType *RT = Ty->getAs<RecordType>()) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); if (RD->isPolymorphic()) return Builder.CreateBitCast(CGM.GenerateRttiRef(RD), LTy); return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); } return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); } Expr *subE = E->getExprOperand(); Ty = subE->getType(); CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); Ty = CanTy.getUnqualifiedType().getNonReferenceType(); if (const RecordType *RT = Ty->getAs<RecordType>()) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); if (RD->isPolymorphic()) { // FIXME: if subE is an lvalue do LValue Obj = EmitLValue(subE); llvm::Value *This = Obj.getAddress(); LTy = LTy->getPointerTo()->getPointerTo(); llvm::Value *V = Builder.CreateBitCast(This, LTy); // We need to do a zero check for *p, unless it has NonNullAttr. // FIXME: PointerType->hasAttr<NonNullAttr>() bool CanBeZero = false; if (UnaryOperator *UO = dyn_cast<UnaryOperator>(subE->IgnoreParens())) if (UO->getOpcode() == UnaryOperator::Deref) CanBeZero = true; if (CanBeZero) { llvm::BasicBlock *NonZeroBlock = createBasicBlock(); llvm::BasicBlock *ZeroBlock = createBasicBlock(); llvm::Value *Zero = llvm::Constant::getNullValue(LTy); Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), NonZeroBlock, ZeroBlock); EmitBlock(ZeroBlock); /// Call __cxa_bad_typeid const llvm::Type *ResultType = llvm::Type::getVoidTy(VMContext); const llvm::FunctionType *FTy; FTy = llvm::FunctionType::get(ResultType, false); llvm::Value *F = CGM.CreateRuntimeFunction(FTy, "__cxa_bad_typeid"); Builder.CreateCall(F)->setDoesNotReturn(); Builder.CreateUnreachable(); EmitBlock(NonZeroBlock); } V = Builder.CreateLoad(V, "vtable"); V = Builder.CreateConstInBoundsGEP1_64(V, -1ULL); V = Builder.CreateLoad(V); return V; } return Builder.CreateBitCast(CGM.GenerateRtti(RD), LTy); } return Builder.CreateBitCast(CGM.GenerateRttiNonClass(Ty), LTy); }
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, ProgramStateRef state, const ObjCMethodCall &Msg) const { ASTContext &Ctx = C.getASTContext(); static CheckerProgramPointTag Tag(this, "NilReceiver"); // Check the return type of the message expression. A message to nil will // return different values depending on the return type and the architecture. QualType RetTy = Msg.getResultType(); CanQualType CanRetTy = Ctx.getCanonicalType(RetTy); const LocationContext *LCtx = C.getLocationContext(); if (CanRetTy->isStructureOrClassType()) { // Structure returns are safe since the compiler zeroes them out. SVal V = C.getSValBuilder().makeZeroVal(RetTy); C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag); return; } // Other cases: check if sizeof(return type) > sizeof(void*) if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap() .isConsumedExpr(Msg.getOriginExpr())) { // Compute: sizeof(void *) and sizeof(return type) const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy); const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy); if (CanRetTy.getTypePtr()->isReferenceType()|| (voidPtrSize < returnTypeSize && !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) && (Ctx.FloatTy == CanRetTy || Ctx.DoubleTy == CanRetTy || Ctx.LongDoubleTy == CanRetTy || Ctx.LongLongTy == CanRetTy || Ctx.UnsignedLongLongTy == CanRetTy)))) { if (ExplodedNode *N = C.generateSink(state, nullptr, &Tag)) emitNilReceiverBug(C, Msg, N); return; } // Handle the safe cases where the return value is 0 if the // receiver is nil. // // FIXME: For now take the conservative approach that we only // return null values if we *know* that the receiver is nil. // This is because we can have surprises like: // // ... = [[NSScreens screens] objectAtIndex:0]; // // What can happen is that [... screens] could return nil, but // it most likely isn't nil. We should assume the semantics // of this case unless we have *a lot* more knowledge. // SVal V = C.getSValBuilder().makeZeroVal(RetTy); C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V), &Tag); return; } C.addTransition(state); }
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, Cl::Kinds Kind, SourceLocation &Loc) { // As a general rule, we only care about lvalues. But there are some rvalues // for which we want to generate special results. if (Kind == Cl::CL_PRValue) { // For the sake of better diagnostics, we want to specifically recognize // use of the GCC cast-as-lvalue extension. if (const ExplicitCastExpr *CE = dyn_cast<ExplicitCastExpr>(E->IgnoreParens())) { if (CE->getSubExpr()->IgnoreParenImpCasts()->isLValue()) { Loc = CE->getExprLoc(); return Cl::CM_LValueCast; } } } if (Kind != Cl::CL_LValue) return Cl::CM_RValue; // This is the lvalue case. // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6) if (Ctx.getLangOpts().CPlusPlus && E->getType()->isFunctionType()) return Cl::CM_Function; // Assignment to a property in ObjC is an implicit setter access. But a // setter might not exist. if (const ObjCPropertyRefExpr *Expr = dyn_cast<ObjCPropertyRefExpr>(E)) { if (Expr->isImplicitProperty() && Expr->getImplicitPropertySetter() == 0) return Cl::CM_NoSetterProperty; } CanQualType CT = Ctx.getCanonicalType(E->getType()); // Const stuff is obviously not modifiable. if (CT.isConstQualified()) return Cl::CM_ConstQualified; if (CT.getQualifiers().getAddressSpace() == LangAS::opencl_constant) return Cl::CM_ConstQualified; // Arrays are not modifiable, only their elements are. if (CT->isArrayType()) return Cl::CM_ArrayType; // Incomplete types are not modifiable. if (CT->isIncompleteType()) return Cl::CM_IncompleteType; // Records with any const fields (recursively) are not modifiable. if (const RecordType *R = CT->getAs<RecordType>()) { assert((E->getObjectKind() == OK_ObjCProperty || !Ctx.getLangOpts().CPlusPlus) && "C++ struct assignment should be resolved by the " "copy assignment operator."); if (R->hasConstFields()) return Cl::CM_ConstQualified; } return Cl::CM_Modifiable; }
// Asks whether the type in 'context' can ever instantiate to the type // in 'friend'. static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) { if (Friend == Context) return true; if (!Friend->isDependentType() && !Context->isDependentType()) return false; // TODO: this is very conservative. return true; }
DeclarationName DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty) { assert(Kind >= DeclarationName::CXXConstructorName && Kind <= DeclarationName::CXXConversionFunctionName && "Kind must be a C++ special name kind"); llvm::FoldingSet<CXXSpecialName> *SpecialNames = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); DeclarationNameExtra::ExtraKind EKind; switch (Kind) { case DeclarationName::CXXConstructorName: EKind = DeclarationNameExtra::CXXConstructor; assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); break; case DeclarationName::CXXDestructorName: EKind = DeclarationNameExtra::CXXDestructor; assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); break; case DeclarationName::CXXConversionFunctionName: EKind = DeclarationNameExtra::CXXConversionFunction; break; default: return DeclarationName(); } // Unique selector, to guarantee there is one per name. llvm::FoldingSetNodeID ID; ID.AddInteger(EKind); ID.AddPointer(Ty.getAsOpaquePtr()); void *InsertPos = nullptr; if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) return DeclarationName(Name); CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; SpecialName->ExtraKindOrNumArgs = EKind; SpecialName->Type = Ty; SpecialName->FETokenInfo = nullptr; SpecialNames->InsertNode(SpecialName, InsertPos); return DeclarationName(SpecialName); }
static AccessResult MatchesFriend(Sema &S, const EffectiveContext &EC, CanQualType Friend) { if (const RecordType *RT = Friend->getAs<RecordType>()) return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl())); // TODO: we can do better than this if (Friend->isDependentType()) return AR_dependent; return AR_inaccessible; }
/// Emit an alloca (or GlobalValue depending on target) /// for the specified parameter and set up LocalDeclMap. void CodeGenFunction::EmitParmDecl(const VarDecl &D, llvm::Value *Arg) { // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl? assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) && "Invalid argument to EmitParmDecl"); QualType Ty = D.getType(); CanQualType CTy = getContext().getCanonicalType(Ty); llvm::Value *DeclPtr; if (!Ty->isConstantSizeType()) { // Variable sized values always are passed by-reference. DeclPtr = Arg; } else { // A fixed sized single-value variable becomes an alloca in the entry block. const llvm::Type *LTy = ConvertTypeForMem(Ty); if (LTy->isSingleValueType()) { // TODO: Alignment DeclPtr = CreateTempAlloca(LTy); DeclPtr->setName(D.getNameAsString() + llvm::StringRef(".addr")); // Store the initial value into the alloca. EmitStoreOfScalar(Arg, DeclPtr, CTy.isVolatileQualified(), Ty); } else { // Otherwise, if this is an aggregate, just use the input pointer. DeclPtr = Arg; } Arg->setName(D.getNameAsString()); } llvm::Value *&DMEntry = LocalDeclMap[&D]; assert(DMEntry == 0 && "Decl already exists in localdeclmap!"); DMEntry = DeclPtr; // Emit debug info for param declaration. if (CGDebugInfo *DI = getDebugInfo()) { DI->setLocation(D.getLocation()); DI->EmitDeclareOfArgVariable(&D, DeclPtr, Builder); } }
bool CXXConstructorDecl::isCopyConstructor(unsigned &TypeQuals) const { // C++ [class.copy]p2: // A non-template constructor for class X is a copy constructor // if its first parameter is of type X&, const X&, volatile X& or // const volatile X&, and either there are no other parameters // or else all other parameters have default arguments (8.3.6). if ((getNumParams() < 1) || (getNumParams() > 1 && !getParamDecl(1)->hasDefaultArg()) || (getPrimaryTemplate() != 0) || (getDescribedFunctionTemplate() != 0)) return false; const ParmVarDecl *Param = getParamDecl(0); // Do we have a reference type? Rvalue references don't count. const LValueReferenceType *ParamRefType = Param->getType()->getAs<LValueReferenceType>(); if (!ParamRefType) return false; // Is it a reference to our class type? ASTContext &Context = getASTContext(); CanQualType PointeeType = Context.getCanonicalType(ParamRefType->getPointeeType()); CanQualType ClassTy = Context.getCanonicalType(Context.getTagDeclType(getParent())); if (PointeeType.getUnqualifiedType() != ClassTy) return false; // FIXME: other qualifiers? // We have a copy constructor. TypeQuals = PointeeType.getCVRQualifiers(); return true; }
void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C, const ProgramState *state, ObjCMessage msg) const { ASTContext &Ctx = C.getASTContext(); // Check the return type of the message expression. A message to nil will // return different values depending on the return type and the architecture. QualType RetTy = msg.getType(Ctx); CanQualType CanRetTy = Ctx.getCanonicalType(RetTy); if (CanRetTy->isStructureOrClassType()) { // FIXME: At some point we shouldn't rely on isConsumedExpr(), but instead // have the "use of undefined value" be smarter about where the // undefined value came from. if (C.getPredecessor()->getParentMap().isConsumedExpr(msg.getOriginExpr())){ if (ExplodedNode *N = C.generateSink(state)) emitNilReceiverBug(C, msg, N); return; } // The result is not consumed by a surrounding expression. Just propagate // the current state. C.addTransition(state); return; } // Other cases: check if the return type is smaller than void*. if (CanRetTy != Ctx.VoidTy && C.getPredecessor()->getParentMap().isConsumedExpr(msg.getOriginExpr())) { // Compute: sizeof(void *) and sizeof(return type) const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy); const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy); if (voidPtrSize < returnTypeSize && !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) && (Ctx.FloatTy == CanRetTy || Ctx.DoubleTy == CanRetTy || Ctx.LongDoubleTy == CanRetTy || Ctx.LongLongTy == CanRetTy || Ctx.UnsignedLongLongTy == CanRetTy))) { if (ExplodedNode *N = C.generateSink(state)) emitNilReceiverBug(C, msg, N); return; } // Handle the safe cases where the return value is 0 if the // receiver is nil. // // FIXME: For now take the conservative approach that we only // return null values if we *know* that the receiver is nil. // This is because we can have surprises like: // // ... = [[NSScreens screens] objectAtIndex:0]; // // What can happen is that [... screens] could return nil, but // it most likely isn't nil. We should assume the semantics // of this case unless we have *a lot* more knowledge. // SVal V = C.getSValBuilder().makeZeroVal(msg.getType(Ctx)); C.generateNode(state->BindExpr(msg.getOriginExpr(), V)); return; } C.addTransition(state); }
/// isAmbiguous - Determines whether the set of paths provided is /// ambiguous, i.e., there are two or more paths that refer to /// different base class subobjects of the same type. BaseType must be /// an unqualified, canonical class type. bool CXXBasePaths::isAmbiguous(CanQualType BaseType) { BaseType = BaseType.getUnqualifiedType(); std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType]; return Subobjects.second + (Subobjects.first? 1 : 0) > 1; }
llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *V, const CXXDynamicCastExpr *DCE) { QualType CastTy = DCE->getTypeAsWritten(); QualType InnerType = CastTy->getPointeeType(); QualType ArgTy = DCE->getSubExpr()->getType(); const llvm::Type *LArgTy = ConvertType(ArgTy); const llvm::Type *LTy = ConvertType(DCE->getType()); bool CanBeZero = false; bool ToVoid = false; bool ThrowOnBad = false; if (CastTy->isPointerType()) { // FIXME: if PointerType->hasAttr<NonNullAttr>(), we don't set this CanBeZero = true; if (InnerType->isVoidType()) ToVoid = true; } else { LTy = LTy->getPointerTo(); ThrowOnBad = true; } CXXRecordDecl *SrcTy; QualType Ty = ArgTy; if (ArgTy.getTypePtr()->isPointerType() || ArgTy.getTypePtr()->isReferenceType()) Ty = Ty.getTypePtr()->getPointeeType(); CanQualType CanTy = CGM.getContext().getCanonicalType(Ty); Ty = CanTy.getUnqualifiedType(); SrcTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); llvm::BasicBlock *ContBlock = createBasicBlock(); llvm::BasicBlock *NullBlock = 0; llvm::BasicBlock *NonZeroBlock = 0; if (CanBeZero) { NonZeroBlock = createBasicBlock(); NullBlock = createBasicBlock(); llvm::Value *Zero = llvm::Constant::getNullValue(LArgTy); Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), NonZeroBlock, NullBlock); EmitBlock(NonZeroBlock); } llvm::BasicBlock *BadCastBlock = 0; const llvm::Type *PtrDiffTy = ConvertType(getContext().getSizeType()); // See if this is a dynamic_cast(void*) if (ToVoid) { llvm::Value *This = V; V = Builder.CreateBitCast(This, PtrDiffTy->getPointerTo()->getPointerTo()); V = Builder.CreateLoad(V, "vtable"); V = Builder.CreateConstInBoundsGEP1_64(V, -2ULL); V = Builder.CreateLoad(V, "offset to top"); This = Builder.CreateBitCast(This, llvm::Type::getInt8PtrTy(VMContext)); V = Builder.CreateInBoundsGEP(This, V); V = Builder.CreateBitCast(V, LTy); } else { /// Call __dynamic_cast const llvm::Type *ResultType = llvm::Type::getInt8PtrTy(VMContext); const llvm::FunctionType *FTy; std::vector<const llvm::Type*> ArgTys; const llvm::Type *PtrToInt8Ty = llvm::Type::getInt8Ty(VMContext)->getPointerTo(); ArgTys.push_back(PtrToInt8Ty); ArgTys.push_back(PtrToInt8Ty); ArgTys.push_back(PtrToInt8Ty); ArgTys.push_back(PtrDiffTy); FTy = llvm::FunctionType::get(ResultType, ArgTys, false); CXXRecordDecl *DstTy; Ty = CastTy.getTypePtr()->getPointeeType(); CanTy = CGM.getContext().getCanonicalType(Ty); Ty = CanTy.getUnqualifiedType(); DstTy = cast<CXXRecordDecl>(Ty->getAs<RecordType>()->getDecl()); // FIXME: Calculate better hint. llvm::Value *hint = llvm::ConstantInt::get(PtrDiffTy, -1ULL); llvm::Value *SrcArg = CGM.GenerateRttiRef(SrcTy); llvm::Value *DstArg = CGM.GenerateRttiRef(DstTy); V = Builder.CreateBitCast(V, PtrToInt8Ty); V = Builder.CreateCall4(CGM.CreateRuntimeFunction(FTy, "__dynamic_cast"), V, SrcArg, DstArg, hint); V = Builder.CreateBitCast(V, LTy); if (ThrowOnBad) { BadCastBlock = createBasicBlock(); llvm::Value *Zero = llvm::Constant::getNullValue(LTy); Builder.CreateCondBr(Builder.CreateICmpNE(V, Zero), ContBlock, BadCastBlock); EmitBlock(BadCastBlock); /// Call __cxa_bad_cast ResultType = llvm::Type::getVoidTy(VMContext); const llvm::FunctionType *FBadTy; FBadTy = llvm::FunctionType::get(ResultType, false); llvm::Value *F = CGM.CreateRuntimeFunction(FBadTy, "__cxa_bad_cast"); Builder.CreateCall(F)->setDoesNotReturn(); Builder.CreateUnreachable(); } } if (CanBeZero) { Builder.CreateBr(ContBlock); EmitBlock(NullBlock); Builder.CreateBr(ContBlock); } EmitBlock(ContBlock); if (CanBeZero) { llvm::PHINode *PHI = Builder.CreatePHI(LTy); PHI->reserveOperandSpace(2); PHI->addIncoming(V, NonZeroBlock); PHI->addIncoming(llvm::Constant::getNullValue(LTy), NullBlock); V = PHI; } return V; }
static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E, Cl::Kinds Kind, SourceLocation &Loc) { // As a general rule, we only care about lvalues. But there are some rvalues // for which we want to generate special results. if (Kind == Cl::CL_PRValue) { // For the sake of better diagnostics, we want to specifically recognize // use of the GCC cast-as-lvalue extension. if (const CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(E->IgnoreParens())){ if (CE->getSubExpr()->Classify(Ctx).isLValue()) { Loc = CE->getLParenLoc(); return Cl::CM_LValueCast; } } } if (Kind != Cl::CL_LValue) return Cl::CM_RValue; // This is the lvalue case. // Functions are lvalues in C++, but not modifiable. (C++ [basic.lval]p6) if (Ctx.getLangOptions().CPlusPlus && E->getType()->isFunctionType()) return Cl::CM_Function; // You cannot assign to a variable outside a block from within the block if // it is not marked __block, e.g. // void takeclosure(void (^C)(void)); // void func() { int x = 1; takeclosure(^{ x = 7; }); } if (const BlockDeclRefExpr *BDR = dyn_cast<BlockDeclRefExpr>(E)) { if (!BDR->isByRef() && isa<VarDecl>(BDR->getDecl())) return Cl::CM_NotBlockQualified; } // Assignment to a property in ObjC is an implicit setter access. But a // setter might not exist. if (const ObjCImplicitSetterGetterRefExpr *Expr = dyn_cast<ObjCImplicitSetterGetterRefExpr>(E)) { if (Expr->getSetterMethod() == 0) return Cl::CM_NoSetterProperty; } CanQualType CT = Ctx.getCanonicalType(E->getType()); // Const stuff is obviously not modifiable. if (CT.isConstQualified()) return Cl::CM_ConstQualified; // Arrays are not modifiable, only their elements are. if (CT->isArrayType()) return Cl::CM_ArrayType; // Incomplete types are not modifiable. if (CT->isIncompleteType()) return Cl::CM_IncompleteType; // Records with any const fields (recursively) are not modifiable. if (const RecordType *R = CT->getAs<RecordType>()) { assert(!Ctx.getLangOptions().CPlusPlus && "C++ struct assignment should be resolved by the " "copy assignment operator."); if (R->hasConstFields()) return Cl::CM_ConstQualified; } return Cl::CM_Modifiable; }
DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { return getCXXSpecialName(DeclarationName::CXXDestructorName, Ty.getUnqualifiedType()); }