本文整理汇总了C++中QualType类的典型用法代码示例。如果您正苦于以下问题:C++ QualType类的具体用法?C++ QualType怎么用?C++ QualType使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了QualType类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: switch
bool Declarator::isDeclarationOfFunction() const {
for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
switch (DeclTypeInfo[i].Kind) {
case DeclaratorChunk::Function:
return true;
case DeclaratorChunk::Paren:
continue;
case DeclaratorChunk::Pointer:
case DeclaratorChunk::Reference:
case DeclaratorChunk::Array:
case DeclaratorChunk::BlockPointer:
case DeclaratorChunk::MemberPointer:
return false;
}
llvm_unreachable("Invalid type chunk");
}
switch (DS.getTypeSpecType()) {
case TST_atomic:
case TST_auto:
case TST_bool:
case TST_char:
case TST_char16:
case TST_char32:
case TST_class:
case TST_decimal128:
case TST_decimal32:
case TST_decimal64:
case TST_double:
case TST_enum:
case TST_error:
case TST_float:
case TST_half:
case TST_int:
case TST_int128:
case TST_struct:
case TST_interface:
case TST_union:
case TST_unknown_anytype:
case TST_unspecified:
case TST_void:
case TST_wchar:
return false;
case TST_decltype:
case TST_typeofExpr:
if (Expr *E = DS.getRepAsExpr())
return E->getType()->isFunctionType();
return false;
case TST_underlyingType:
case TST_typename:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
if (QT.isNull())
return false;
if (const LocInfoType *LIT = dyn_cast<LocInfoType>(QT))
QT = LIT->getType();
if (QT.isNull())
return false;
return QT->isFunctionType();
}
}
llvm_unreachable("Invalid TypeSpecType!");
}
示例2: ArgEffect
bool RetainSummaryManager::applyParamAnnotationEffect(
const ParmVarDecl *pd, unsigned parm_idx, const NamedDecl *FD,
RetainSummaryTemplate &Template) {
QualType QT = pd->getType();
if (auto K =
hasAnyEnabledAttrOf<NSConsumedAttr, CFConsumedAttr, OSConsumedAttr,
GeneralizedConsumedAttr>(pd, QT)) {
Template->addArg(AF, parm_idx, ArgEffect(DecRef, *K));
return true;
} else if (auto K = hasAnyEnabledAttrOf<
CFReturnsRetainedAttr, OSReturnsRetainedAttr,
OSReturnsRetainedOnNonZeroAttr, OSReturnsRetainedOnZeroAttr,
GeneralizedReturnsRetainedAttr>(pd, QT)) {
// For OSObjects, we try to guess whether the object is created based
// on the return value.
if (K == ObjKind::OS) {
QualType QT = getCallableReturnType(FD);
bool HasRetainedOnZero = pd->hasAttr<OSReturnsRetainedOnZeroAttr>();
bool HasRetainedOnNonZero = pd->hasAttr<OSReturnsRetainedOnNonZeroAttr>();
// The usual convention is to create an object on non-zero return, but
// it's reverted if the typedef chain has a typedef kern_return_t,
// because kReturnSuccess constant is defined as zero.
// The convention can be overwritten by custom attributes.
bool SuccessOnZero =
HasRetainedOnZero ||
(hasTypedefNamed(QT, "kern_return_t") && !HasRetainedOnNonZero);
bool ShouldSplit = !QT.isNull() && !QT->isVoidType();
ArgEffectKind AK = RetainedOutParameter;
if (ShouldSplit && SuccessOnZero) {
AK = RetainedOutParameterOnZero;
} else if (ShouldSplit && (!SuccessOnZero || HasRetainedOnNonZero)) {
AK = RetainedOutParameterOnNonZero;
}
Template->addArg(AF, parm_idx, ArgEffect(AK, ObjKind::OS));
}
// For others:
// Do nothing. Retained out parameters will either point to a +1 reference
// or NULL, but the way you check for failure differs depending on the
// API. Consequently, we don't have a good way to track them yet.
return true;
} else if (auto K = hasAnyEnabledAttrOf<CFReturnsNotRetainedAttr,
OSReturnsNotRetainedAttr,
GeneralizedReturnsNotRetainedAttr>(
pd, QT)) {
Template->addArg(AF, parm_idx, ArgEffect(UnretainedOutParameter, *K));
return true;
}
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
for (const auto *OD : MD->overridden_methods()) {
const ParmVarDecl *OP = OD->parameters()[parm_idx];
if (applyParamAnnotationEffect(OP, parm_idx, OD, Template))
return true;
}
}
return false;
}
示例3: CheckConstCast
/// CheckConstCast - Check that a const_cast\<DestType\>(SrcExpr) is valid.
/// Refer to C++ 5.2.11 for details. const_cast is typically used in code
/// like this:
/// const char *str = "literal";
/// legacy_function(const_cast\<char*\>(str));
void
CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
const SourceRange &OpRange, const SourceRange &DestRange)
{
QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType();
DestType = Self.Context.getCanonicalType(DestType);
QualType SrcType = SrcExpr->getType();
if (const LValueReferenceType *DestTypeTmp =
DestType->getAsLValueReferenceType()) {
if (SrcExpr->isLvalue(Self.Context) != Expr::LV_Valid) {
// Cannot cast non-lvalue to lvalue reference type.
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)
<< "const_cast" << OrigDestType << SrcExpr->getSourceRange();
return;
}
// C++ 5.2.11p4: An lvalue of type T1 can be [cast] to an lvalue of type T2
// [...] if a pointer to T1 can be [cast] to the type pointer to T2.
DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());
SrcType = Self.Context.getPointerType(SrcType);
} else {
// C++ 5.2.11p1: Otherwise, the result is an rvalue and the
// lvalue-to-rvalue, array-to-pointer, and function-to-pointer standard
// conversions are performed on the expression.
Self.DefaultFunctionArrayConversion(SrcExpr);
SrcType = SrcExpr->getType();
}
// C++ 5.2.11p5: For a const_cast involving pointers to data members [...]
// the rules for const_cast are the same as those used for pointers.
if (!DestType->isPointerType() && !DestType->isMemberPointerType()) {
// Cannot cast to non-pointer, non-reference type. Note that, if DestType
// was a reference type, we converted it to a pointer above.
// The status of rvalue references isn't entirely clear, but it looks like
// conversion to them is simply invalid.
// C++ 5.2.11p3: For two pointer types [...]
Self.Diag(OpRange.getBegin(), diag::err_bad_const_cast_dest)
<< OrigDestType << DestRange;
return;
}
if (DestType->isFunctionPointerType() ||
DestType->isMemberFunctionPointerType()) {
// Cannot cast direct function pointers.
// C++ 5.2.11p2: [...] where T is any object type or the void type [...]
// T is the ultimate pointee of source and target type.
Self.Diag(OpRange.getBegin(), diag::err_bad_const_cast_dest)
<< OrigDestType << DestRange;
return;
}
SrcType = Self.Context.getCanonicalType(SrcType);
// Unwrap the pointers. Ignore qualifiers. Terminate early if the types are
// completely equal.
// FIXME: const_cast should probably not be able to convert between pointers
// to different address spaces.
// C++ 5.2.11p3 describes the core semantics of const_cast. All cv specifiers
// in multi-level pointers may change, but the level count must be the same,
// as must be the final pointee type.
while (SrcType != DestType &&
Self.UnwrapSimilarPointerTypes(SrcType, DestType)) {
SrcType = SrcType.getUnqualifiedType();
DestType = DestType.getUnqualifiedType();
}
// Doug Gregor said to disallow this until users complain.
#if 0
// If we end up with constant arrays of equal size, unwrap those too. A cast
// from const int [N] to int (&)[N] is invalid by my reading of the
// standard, but g++ accepts it even with -ansi -pedantic.
// No more than one level, though, so don't embed this in the unwrap loop
// above.
const ConstantArrayType *SrcTypeArr, *DestTypeArr;
if ((SrcTypeArr = Self.Context.getAsConstantArrayType(SrcType)) &&
(DestTypeArr = Self.Context.getAsConstantArrayType(DestType)))
{
if (SrcTypeArr->getSize() != DestTypeArr->getSize()) {
// Different array sizes.
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
<< "const_cast" << OrigDestType << OrigSrcType << OpRange;
return;
}
SrcType = SrcTypeArr->getElementType().getUnqualifiedType();
DestType = DestTypeArr->getElementType().getUnqualifiedType();
}
#endif
// Since we're dealing in canonical types, the remainder must be the same.
if (SrcType != DestType) {
// Cast between unrelated types.
Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)
<< "const_cast" << OrigDestType << OrigSrcType << OpRange;
return;
}
//.........这里部分代码省略.........
示例4: isISLObjectRef
static bool isISLObjectRef(QualType Ty) {
return StringRef(Ty.getAsString()).startswith("isl_");
}
示例5: assert
ExprResult
Sema::BuildAnonymousStructUnionMemberReference(SourceLocation loc,
IndirectFieldDecl *indirectField,
Expr *baseObjectExpr,
SourceLocation opLoc) {
// First, build the expression that refers to the base object.
bool baseObjectIsPointer = false;
Qualifiers baseQuals;
// Case 1: the base of the indirect field is not a field.
VarDecl *baseVariable = indirectField->getVarDecl();
CXXScopeSpec EmptySS;
if (baseVariable) {
assert(baseVariable->getType()->isRecordType());
// In principle we could have a member access expression that
// accesses an anonymous struct/union that's a static member of
// the base object's class. However, under the current standard,
// static data members cannot be anonymous structs or unions.
// Supporting this is as easy as building a MemberExpr here.
assert(!baseObjectExpr && "anonymous struct/union is static data member?");
DeclarationNameInfo baseNameInfo(DeclarationName(), loc);
ExprResult result
= BuildDeclarationNameExpr(EmptySS, baseNameInfo, baseVariable);
if (result.isInvalid()) return ExprError();
baseObjectExpr = result.take();
baseObjectIsPointer = false;
baseQuals = baseObjectExpr->getType().getQualifiers();
// Case 2: the base of the indirect field is a field and the user
// wrote a member expression.
} else if (baseObjectExpr) {
// The caller provided the base object expression. Determine
// whether its a pointer and whether it adds any qualifiers to the
// anonymous struct/union fields we're looking into.
QualType objectType = baseObjectExpr->getType();
if (const PointerType *ptr = objectType->getAs<PointerType>()) {
baseObjectIsPointer = true;
objectType = ptr->getPointeeType();
} else {
baseObjectIsPointer = false;
}
baseQuals = objectType.getQualifiers();
}
// Build the implicit member references to the field of the
// anonymous struct/union.
Expr *result = baseObjectExpr;
IndirectFieldDecl::chain_iterator
FI = indirectField->chain_begin(), FEnd = indirectField->chain_end();
// Build the first member access in the chain with full information.
if (!baseVariable) {
FieldDecl *field = cast<FieldDecl>(*FI);
// FIXME: use the real found-decl info!
DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
// Make a nameInfo that properly uses the anonymous name.
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
result = BuildFieldReferenceExpr(*this, result, baseObjectIsPointer,
EmptySS, field, foundDecl,
memberNameInfo).take();
baseObjectIsPointer = false;
// FIXME: check qualified member access
}
// In all cases, we should now skip the first declaration in the chain.
++FI;
while (FI != FEnd) {
FieldDecl *field = cast<FieldDecl>(*FI++);
// FIXME: these are somewhat meaningless
DeclarationNameInfo memberNameInfo(field->getDeclName(), loc);
DeclAccessPair foundDecl = DeclAccessPair::make(field, field->getAccess());
result = BuildFieldReferenceExpr(*this, result, /*isarrow*/ false,
EmptySS, field,
foundDecl, memberNameInfo).take();
}
return Owned(result);
}
示例6: GetCFNumberSize
void CFNumberCreateChecker::checkPreStmt(const CallExpr *CE,
CheckerContext &C) const {
const ProgramState *state = C.getState();
const FunctionDecl *FD = C.getCalleeDecl(CE);
if (!FD)
return;
ASTContext &Ctx = C.getASTContext();
if (!II)
II = &Ctx.Idents.get("CFNumberCreate");
if (FD->getIdentifier() != II || CE->getNumArgs() != 3)
return;
// Get the value of the "theType" argument.
SVal TheTypeVal = state->getSVal(CE->getArg(1));
// FIXME: We really should allow ranges of valid theType values, and
// bifurcate the state appropriately.
nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);
if (!V)
return;
uint64_t NumberKind = V->getValue().getLimitedValue();
Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);
// FIXME: In some cases we can emit an error.
if (!TargetSize.isKnown())
return;
// Look at the value of the integer being passed by reference. Essentially
// we want to catch cases where the value passed in is not equal to the
// size of the type being created.
SVal TheValueExpr = state->getSVal(CE->getArg(2));
// FIXME: Eventually we should handle arbitrary locations. We can do this
// by having an enhanced memory model that does low-level typing.
loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);
if (!LV)
return;
const TypedValueRegion* R = dyn_cast<TypedValueRegion>(LV->stripCasts());
if (!R)
return;
QualType T = Ctx.getCanonicalType(R->getValueType());
// FIXME: If the pointee isn't an integer type, should we flag a warning?
// People can do weird stuff with pointers.
if (!T->isIntegerType())
return;
uint64_t SourceSize = Ctx.getTypeSize(T);
// CHECK: is SourceSize == TargetSize
if (SourceSize == TargetSize)
return;
// Generate an error. Only generate a sink if 'SourceSize < TargetSize';
// otherwise generate a regular node.
//
// FIXME: We can actually create an abstract "CFNumber" object that has
// the bits initialized to the provided values.
//
if (ExplodedNode *N = SourceSize < TargetSize ? C.generateSink()
: C.addTransition()) {
llvm::SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
os << (SourceSize == 8 ? "An " : "A ")
<< SourceSize << " bit integer is used to initialize a CFNumber "
"object that represents "
<< (TargetSize == 8 ? "an " : "a ")
<< TargetSize << " bit integer. ";
if (SourceSize < TargetSize)
os << (TargetSize - SourceSize)
<< " bits of the CFNumber value will be garbage." ;
else
os << (SourceSize - TargetSize)
<< " bits of the input integer will be lost.";
if (!BT)
BT.reset(new APIMisuse("Bad use of CFNumberCreate"));
BugReport *report = new BugReport(*BT, os.str(), N);
report->addRange(CE->getArg(2)->getSourceRange());
C.EmitReport(report);
}
}
示例7: APIMisuse
void VariadicMethodTypeChecker::checkPreObjCMessage(ObjCMessage msg,
CheckerContext &C) const {
if (!BT) {
BT.reset(new APIMisuse("Arguments passed to variadic method aren't all "
"Objective-C pointer types"));
ASTContext &Ctx = C.getASTContext();
arrayWithObjectsS = GetUnarySelector("arrayWithObjects", Ctx);
dictionaryWithObjectsAndKeysS =
GetUnarySelector("dictionaryWithObjectsAndKeys", Ctx);
setWithObjectsS = GetUnarySelector("setWithObjects", Ctx);
initWithObjectsS = GetUnarySelector("initWithObjects", Ctx);
initWithObjectsAndKeysS = GetUnarySelector("initWithObjectsAndKeys", Ctx);
}
if (!isVariadicMessage(msg))
return;
// We are not interested in the selector arguments since they have
// well-defined types, so the compiler will issue a warning for them.
unsigned variadicArgsBegin = msg.getSelector().getNumArgs();
// We're not interested in the last argument since it has to be nil or the
// compiler would have issued a warning for it elsewhere.
unsigned variadicArgsEnd = msg.getNumArgs() - 1;
if (variadicArgsEnd <= variadicArgsBegin)
return;
// Verify that all arguments have Objective-C types.
llvm::Optional<ExplodedNode*> errorNode;
const ProgramState *state = C.getState();
for (unsigned I = variadicArgsBegin; I != variadicArgsEnd; ++I) {
QualType ArgTy = msg.getArgType(I);
if (ArgTy->isObjCObjectPointerType())
continue;
// Block pointers are treaded as Objective-C pointers.
if (ArgTy->isBlockPointerType())
continue;
// Ignore pointer constants.
if (isa<loc::ConcreteInt>(msg.getArgSVal(I, state)))
continue;
// Ignore pointer types annotated with 'NSObject' attribute.
if (C.getASTContext().isObjCNSObjectType(ArgTy))
continue;
// Ignore CF references, which can be toll-free bridged.
if (coreFoundation::isCFObjectRef(ArgTy))
continue;
// Generate only one error node to use for all bug reports.
if (!errorNode.hasValue()) {
errorNode = C.addTransition();
}
if (!errorNode.getValue())
continue;
llvm::SmallString<128> sbuf;
llvm::raw_svector_ostream os(sbuf);
if (const char *TypeName = GetReceiverNameType(msg))
os << "Argument to '" << TypeName << "' method '";
else
os << "Argument to method '";
os << msg.getSelector().getAsString()
<< "' should be an Objective-C pointer type, not '"
<< ArgTy.getAsString() << "'";
BugReport *R = new BugReport(*BT, os.str(),
errorNode.getValue());
R->addRange(msg.getArgSourceRange(I));
C.EmitReport(R);
}
}
示例8: switch
ObjCMethodFamily ObjCMethodDecl::getMethodFamily() const {
ObjCMethodFamily family = static_cast<ObjCMethodFamily>(Family);
if (family != static_cast<unsigned>(InvalidObjCMethodFamily))
return family;
// Check for an explicit attribute.
if (const ObjCMethodFamilyAttr *attr = getAttr<ObjCMethodFamilyAttr>()) {
// The unfortunate necessity of mapping between enums here is due
// to the attributes framework.
switch (attr->getFamily()) {
case ObjCMethodFamilyAttr::OMF_None: family = OMF_None; break;
case ObjCMethodFamilyAttr::OMF_alloc: family = OMF_alloc; break;
case ObjCMethodFamilyAttr::OMF_copy: family = OMF_copy; break;
case ObjCMethodFamilyAttr::OMF_init: family = OMF_init; break;
case ObjCMethodFamilyAttr::OMF_mutableCopy: family = OMF_mutableCopy; break;
case ObjCMethodFamilyAttr::OMF_new: family = OMF_new; break;
}
Family = static_cast<unsigned>(family);
return family;
}
family = getSelector().getMethodFamily();
switch (family) {
case OMF_None: break;
// init only has a conventional meaning for an instance method, and
// it has to return an object.
case OMF_init:
if (!isInstanceMethod() || !getResultType()->isObjCObjectPointerType())
family = OMF_None;
break;
// alloc/copy/new have a conventional meaning for both class and
// instance methods, but they require an object return.
case OMF_alloc:
case OMF_copy:
case OMF_mutableCopy:
case OMF_new:
if (!getResultType()->isObjCObjectPointerType())
family = OMF_None;
break;
// These selectors have a conventional meaning only for instance methods.
case OMF_dealloc:
case OMF_finalize:
case OMF_retain:
case OMF_release:
case OMF_autorelease:
case OMF_retainCount:
case OMF_self:
if (!isInstanceMethod())
family = OMF_None;
break;
case OMF_performSelector:
if (!isInstanceMethod() ||
!getResultType()->isObjCIdType())
family = OMF_None;
else {
unsigned noParams = param_size();
if (noParams < 1 || noParams > 3)
family = OMF_None;
else {
ObjCMethodDecl::arg_type_iterator it = arg_type_begin();
QualType ArgT = (*it);
if (!ArgT->isObjCSelType()) {
family = OMF_None;
break;
}
while (--noParams) {
it++;
ArgT = (*it);
if (!ArgT->isObjCIdType()) {
family = OMF_None;
break;
}
}
}
}
break;
}
// Cache the result.
Family = static_cast<unsigned>(family);
return family;
}
示例9: switch
bool ArgType::matchesType(ASTContext &C, QualType argTy) const {
if (Ptr) {
// It has to be a pointer.
const PointerType *PT = argTy->getAs<PointerType>();
if (!PT)
return false;
// We cannot write through a const qualified pointer.
if (PT->getPointeeType().isConstQualified())
return false;
argTy = PT->getPointeeType();
}
switch (K) {
case InvalidTy:
llvm_unreachable("ArgType must be valid");
case UnknownTy:
return true;
case AnyCharTy: {
if (const EnumType *ETy = argTy->getAs<EnumType>())
argTy = ETy->getDecl()->getIntegerType();
if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
switch (BT->getKind()) {
default:
break;
case BuiltinType::Char_S:
case BuiltinType::SChar:
case BuiltinType::UChar:
case BuiltinType::Char_U:
return true;
}
return false;
}
case SpecificTy: {
if (const EnumType *ETy = argTy->getAs<EnumType>())
argTy = ETy->getDecl()->getIntegerType();
argTy = C.getCanonicalType(argTy).getUnqualifiedType();
if (T == argTy)
return true;
// Check for "compatible types".
if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
switch (BT->getKind()) {
default:
break;
case BuiltinType::Char_S:
case BuiltinType::SChar:
case BuiltinType::Char_U:
case BuiltinType::UChar:
return T == C.UnsignedCharTy || T == C.SignedCharTy;
case BuiltinType::Short:
return T == C.UnsignedShortTy;
case BuiltinType::UShort:
return T == C.ShortTy;
case BuiltinType::Int:
return T == C.UnsignedIntTy;
case BuiltinType::UInt:
return T == C.IntTy;
case BuiltinType::Long:
return T == C.UnsignedLongTy;
case BuiltinType::ULong:
return T == C.LongTy;
case BuiltinType::LongLong:
return T == C.UnsignedLongLongTy;
case BuiltinType::ULongLong:
return T == C.LongLongTy;
}
return false;
}
case CStrTy: {
const PointerType *PT = argTy->getAs<PointerType>();
if (!PT)
return false;
QualType pointeeTy = PT->getPointeeType();
if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
switch (BT->getKind()) {
case BuiltinType::Void:
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::Char_S:
case BuiltinType::SChar:
return true;
default:
break;
}
return false;
}
case WCStrTy: {
const PointerType *PT = argTy->getAs<PointerType>();
if (!PT)
return false;
QualType pointeeTy =
//.........这里部分代码省略.........
示例10: switch
SVal Environment::GetSVal(const Stmt *E, ValueManager& ValMgr) const {
for (;;) {
switch (E->getStmtClass()) {
case Stmt::AddrLabelExprClass:
return ValMgr.makeLoc(cast<AddrLabelExpr>(E));
// ParenExprs are no-ops.
case Stmt::ParenExprClass:
E = cast<ParenExpr>(E)->getSubExpr();
continue;
case Stmt::CharacterLiteralClass: {
const CharacterLiteral* C = cast<CharacterLiteral>(E);
return ValMgr.makeIntVal(C->getValue(), C->getType());
}
case Stmt::CXXBoolLiteralExprClass: {
const SVal *X = ExprBindings.lookup(E);
if (X)
return *X;
else
return ValMgr.makeIntVal(cast<CXXBoolLiteralExpr>(E));
}
case Stmt::IntegerLiteralClass: {
// In C++, this expression may have been bound to a temporary object.
SVal const *X = ExprBindings.lookup(E);
if (X)
return *X;
else
return ValMgr.makeIntVal(cast<IntegerLiteral>(E));
}
// Casts where the source and target type are the same
// are no-ops. We blast through these to get the descendant
// subexpression that has a value.
case Stmt::ImplicitCastExprClass:
case Stmt::CStyleCastExprClass: {
const CastExpr* C = cast<CastExpr>(E);
QualType CT = C->getType();
if (CT->isVoidType())
return UnknownVal();
break;
}
// Handle all other Stmt* using a lookup.
default:
break;
};
break;
}
return LookupExpr(E);
}
示例11: assert
const ProgramState *SimpleConstraintManager::assumeSymRel(const ProgramState *state,
const SymExpr *LHS,
BinaryOperator::Opcode op,
const llvm::APSInt& Int) {
assert(BinaryOperator::isComparisonOp(op) &&
"Non-comparison ops should be rewritten as comparisons to zero.");
// We only handle simple comparisons of the form "$sym == constant"
// or "($sym+constant1) == constant2".
// The adjustment is "constant1" in the above expression. It's used to
// "slide" the solution range around for modular arithmetic. For example,
// x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
// in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
// the subclasses of SimpleConstraintManager to handle the adjustment.
llvm::APSInt Adjustment;
// First check if the LHS is a simple symbol reference.
SymbolRef Sym = dyn_cast<SymbolData>(LHS);
if (Sym) {
Adjustment = 0;
} else {
// Next, see if it's a "($sym+constant1)" expression.
const SymIntExpr *SE = dyn_cast<SymIntExpr>(LHS);
// We don't handle "($sym1+$sym2)".
// Give up and assume the constraint is feasible.
if (!SE)
return state;
// We don't handle "(<expr>+constant1)".
// Give up and assume the constraint is feasible.
Sym = dyn_cast<SymbolData>(SE->getLHS());
if (!Sym)
return state;
// Get the constant out of the expression "($sym+constant1)".
switch (SE->getOpcode()) {
case BO_Add:
Adjustment = SE->getRHS();
break;
case BO_Sub:
Adjustment = -SE->getRHS();
break;
default:
// We don't handle non-additive operators.
// Give up and assume the constraint is feasible.
return state;
}
}
// FIXME: This next section is a hack. It silently converts the integers to
// be of the same type as the symbol, which is not always correct. Really the
// comparisons should be performed using the Int's type, then mapped back to
// the symbol's range of values.
ProgramStateManager &StateMgr = state->getStateManager();
ASTContext &Ctx = StateMgr.getContext();
QualType T = Sym->getType(Ctx);
assert(T->isIntegerType() || Loc::isLocType(T));
unsigned bitwidth = Ctx.getTypeSize(T);
bool isSymUnsigned
= T->isUnsignedIntegerOrEnumerationType() || Loc::isLocType(T);
// Convert the adjustment.
Adjustment.setIsUnsigned(isSymUnsigned);
Adjustment = Adjustment.extOrTrunc(bitwidth);
// Convert the right-hand side integer.
llvm::APSInt ConvertedInt(Int, isSymUnsigned);
ConvertedInt = ConvertedInt.extOrTrunc(bitwidth);
switch (op) {
default:
// No logic yet for other operators. assume the constraint is feasible.
return state;
case BO_EQ:
return assumeSymEQ(state, Sym, ConvertedInt, Adjustment);
case BO_NE:
return assumeSymNE(state, Sym, ConvertedInt, Adjustment);
case BO_GT:
return assumeSymGT(state, Sym, ConvertedInt, Adjustment);
case BO_GE:
return assumeSymGE(state, Sym, ConvertedInt, Adjustment);
case BO_LT:
return assumeSymLT(state, Sym, ConvertedInt, Adjustment);
case BO_LE:
return assumeSymLE(state, Sym, ConvertedInt, Adjustment);
} // end switch
}
示例12: isRecordType
static bool isRecordType(QualType T) {
return T->isRecordType();
}
示例13: checkPreCall
void AttrNonNullChecker::checkPreCall(const CallEvent &Call,
CheckerContext &C) const {
const Decl *FD = Call.getDecl();
if (!FD)
return;
const NonNullAttr *Att = FD->getAttr<NonNullAttr>();
if (!Att)
return;
ProgramStateRef state = C.getState();
// Iterate through the arguments of CE and check them for null.
for (unsigned idx = 0, count = Call.getNumArgs(); idx != count; ++idx) {
if (!Att->isNonNull(idx))
continue;
SVal V = Call.getArgSVal(idx);
Optional<DefinedSVal> DV = V.getAs<DefinedSVal>();
// If the value is unknown or undefined, we can't perform this check.
if (!DV)
continue;
if (!DV->getAs<Loc>()) {
// If the argument is a union type, we want to handle a potential
// transparent_union GCC extension.
const Expr *ArgE = Call.getArgExpr(idx);
if (!ArgE)
continue;
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
continue;
if (Optional<nonloc::CompoundVal> CSV =
DV->getAs<nonloc::CompoundVal>()) {
nonloc::CompoundVal::iterator CSV_I = CSV->begin();
assert(CSV_I != CSV->end());
V = *CSV_I;
DV = V.getAs<DefinedSVal>();
assert(++CSV_I == CSV->end());
if (!DV)
continue;
} else {
// FIXME: Handle LazyCompoundVals?
continue;
}
}
ConstraintManager &CM = C.getConstraintManager();
ProgramStateRef stateNotNull, stateNull;
llvm::tie(stateNotNull, stateNull) = CM.assumeDual(state, *DV);
if (stateNull && !stateNotNull) {
// Generate an error node. Check for a null node in case
// we cache out.
if (ExplodedNode *errorNode = C.generateSink(stateNull)) {
// Lazily allocate the BugType object if it hasn't already been
// created. Ownership is transferred to the BugReporter object once
// the BugReport is passed to 'EmitWarning'.
if (!BT)
BT.reset(new BugType("Argument with 'nonnull' attribute passed null",
"API"));
BugReport *R =
new BugReport(*BT, "Null pointer passed as an argument to a "
"'nonnull' parameter", errorNode);
// Highlight the range of the argument that was null.
R->addRange(Call.getArgSourceRange(idx));
if (const Expr *ArgE = Call.getArgExpr(idx))
bugreporter::trackNullOrUndefValue(errorNode, ArgE, *R);
// Emit the bug report.
C.emitReport(R);
}
// Always return. Either we cached out or we just emitted an error.
return;
}
// If a pointer value passed the check we should assume that it is
// indeed not null from this point forward.
assert(stateNotNull);
state = stateNotNull;
}
// If we reach here all of the arguments passed the nonnull check.
// If 'state' has been updated generated a new node.
C.addTransition(state);
}
示例14: getLocalAlignmentForType
/// \brief Returns the alignment of the type source info data block.
unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
if (Ty.isNull()) return 1;
return TypeAligner().Visit(TypeLoc(Ty, nullptr));
}
示例15: M
/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
// Check if we have at least two parameters.
if (D->param_size() != 2)
return 0;
// Check if the first parameter is a pointer to integer type.
const ParmVarDecl *Predicate = D->getParamDecl(0);
QualType PredicateQPtrTy = Predicate->getType();
const PointerType *PredicatePtrTy = PredicateQPtrTy->getAs<PointerType>();
if (!PredicatePtrTy)
return 0;
QualType PredicateTy = PredicatePtrTy->getPointeeType();
if (!PredicateTy->isIntegerType())
return 0;
// Check if the second parameter is the proper block type.
const ParmVarDecl *Block = D->getParamDecl(1);
QualType Ty = Block->getType();
if (!isDispatchBlock(Ty))
return 0;
// Everything checks out. Create a fakse body that checks the predicate,
// sets it, and calls the block. Basically, an AST dump of:
//
// void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
// if (!*predicate) {
// *predicate = 1;
// block();
// }
// }
ASTMaker M(C);
// (1) Create the call.
DeclRefExpr *DR = M.makeDeclRefExpr(Block);
ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
CallExpr *CE = new (C) CallExpr(C, ICE, ArrayRef<Expr*>(), C.VoidTy,
VK_RValue, SourceLocation());
// (2) Create the assignment to the predicate.
IntegerLiteral *IL =
IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
C.IntTy, SourceLocation());
BinaryOperator *B =
M.makeAssignment(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
PredicateTy),
M.makeIntegralCast(IL, PredicateTy),
PredicateTy);
// (3) Create the compound statement.
Stmt *Stmts[2];
Stmts[0] = B;
Stmts[1] = CE;
CompoundStmt *CS = new (C) CompoundStmt(C, Stmts, 2, SourceLocation(),
SourceLocation());
// (4) Create the 'if' condition.
ImplicitCastExpr *LValToRval =
M.makeLvalueToRvalue(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate),
PredicateQPtrTy),
PredicateTy),
PredicateTy);
UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
VK_RValue, OK_Ordinary,
SourceLocation());
// (5) Create the 'if' statement.
IfStmt *If = new (C) IfStmt(C, SourceLocation(), 0, UO, CS);
return If;
}