Vendor import of clang release_40 branch r294123:
https://llvm.org/svn/llvm-project/cfe/branches/release_40@294123
This commit is contained in:
parent
1230633774
commit
b309038422
@ -7190,14 +7190,6 @@ class TransformTypos : public TreeTransform<TransformTypos> {
|
||||
|
||||
ExprResult TransformBlockExpr(BlockExpr *E) { return Owned(E); }
|
||||
|
||||
ExprResult TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
|
||||
return Owned(E);
|
||||
}
|
||||
|
||||
ExprResult TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
|
||||
return Owned(E);
|
||||
}
|
||||
|
||||
ExprResult Transform(Expr *E) {
|
||||
ExprResult Res;
|
||||
while (true) {
|
||||
|
@ -2932,16 +2932,17 @@ class TreeTransform {
|
||||
ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
|
||||
SourceLocation IvarLoc,
|
||||
bool IsArrow, bool IsFreeIvar) {
|
||||
// FIXME: We lose track of the IsFreeIvar bit.
|
||||
CXXScopeSpec SS;
|
||||
DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
|
||||
return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
|
||||
/*FIXME:*/IvarLoc, IsArrow,
|
||||
SS, SourceLocation(),
|
||||
/*FirstQualifierInScope=*/nullptr,
|
||||
NameInfo,
|
||||
/*TemplateArgs=*/nullptr,
|
||||
/*S=*/nullptr);
|
||||
ExprResult Result = getSema().BuildMemberReferenceExpr(
|
||||
BaseArg, BaseArg->getType(),
|
||||
/*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
|
||||
/*FirstQualifierInScope=*/nullptr, NameInfo,
|
||||
/*TemplateArgs=*/nullptr,
|
||||
/*S=*/nullptr);
|
||||
if (IsFreeIvar && Result.isUsable())
|
||||
cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// \brief Build a new Objective-C property reference expression.
|
||||
|
@ -94,11 +94,18 @@ void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
|
||||
bool SuggestStatic = false;
|
||||
os << "Call to '" << FName << "' uses";
|
||||
if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
|
||||
const VarDecl *VD = VR->getDecl();
|
||||
// FIXME: These should have correct memory space and thus should be filtered
|
||||
// out earlier. This branch only fires when we're looking from a block,
|
||||
// which we analyze as a top-level declaration, onto a static local
|
||||
// in a function that contains the block.
|
||||
if (VD->isStaticLocal())
|
||||
return;
|
||||
// We filtered out globals earlier, so it must be a local variable
|
||||
// or a block variable which is under UnknownSpaceRegion.
|
||||
if (VR != R)
|
||||
os << " memory within";
|
||||
if (VR->getDecl()->hasAttr<BlocksAttr>())
|
||||
if (VD->hasAttr<BlocksAttr>())
|
||||
os << " the block variable '";
|
||||
else
|
||||
os << " the local variable '";
|
||||
|
@ -816,9 +816,11 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
|
||||
|
||||
const StackFrameContext *STC = V.get<const StackFrameContext*>();
|
||||
|
||||
if (!STC)
|
||||
if (!STC) {
|
||||
// FIXME: Assign a more sensible memory space to static locals
|
||||
// we see from within blocks that we analyze as top-level declarations.
|
||||
sReg = getUnknownRegion();
|
||||
else {
|
||||
} else {
|
||||
if (D->hasLocalStorage()) {
|
||||
sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
|
||||
? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
|
||||
|
@ -1849,6 +1849,8 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,
|
||||
|
||||
// Function-scoped static variables are default-initialized to 0; if they
|
||||
// have an initializer, it would have been processed by now.
|
||||
// FIXME: This is only true when we're starting analysis from main().
|
||||
// We're losing a lot of coverage here.
|
||||
if (isa<StaticGlobalSpaceRegion>(MS))
|
||||
return svalBuilder.makeZeroVal(T);
|
||||
|
||||
|
@ -107,3 +107,10 @@ void test_block_var_from_outside_block() {
|
||||
};
|
||||
dispatch_once(&once, ^{}); // expected-warning{{Call to 'dispatch_once' uses the block variable 'once' for the predicate value.}}
|
||||
}
|
||||
|
||||
void test_static_var_from_outside_block() {
|
||||
static dispatch_once_t once;
|
||||
^{
|
||||
dispatch_once(&once, ^{}); // no-warning
|
||||
};
|
||||
}
|
||||
|
35
test/Analysis/null-deref-static.m
Normal file
35
test/Analysis/null-deref-static.m
Normal file
@ -0,0 +1,35 @@
|
||||
// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=core,deadcode,alpha.core,debug.ExprInspection -verify %s
|
||||
|
||||
void *malloc(unsigned long);
|
||||
void clang_analyzer_warnIfReached();
|
||||
|
||||
void test_static_from_block() {
|
||||
static int *x;
|
||||
^{
|
||||
*x; // no-warning
|
||||
};
|
||||
}
|
||||
|
||||
void test_static_within_block() {
|
||||
^{
|
||||
static int *x;
|
||||
*x; // expected-warning{{Dereference of null pointer}}
|
||||
};
|
||||
}
|
||||
|
||||
void test_static_control_flow(int y) {
|
||||
static int *x;
|
||||
if (x) {
|
||||
// FIXME: Should be reachable.
|
||||
clang_analyzer_warnIfReached(); // no-warning
|
||||
}
|
||||
if (y) {
|
||||
// We are not sure if this branch is possible, because the developer
|
||||
// may argue that function is always called with y == 1 for the first time.
|
||||
// In this case, we can only advise the developer to add assertions
|
||||
// for suppressing such path.
|
||||
*x; // expected-warning{{Dereference of null pointer}}
|
||||
} else {
|
||||
x = malloc(1);
|
||||
}
|
||||
}
|
@ -21,3 +21,18 @@ public:
|
||||
self.m_prop2 = new ClassB(m_prop1); // expected-error {{use of undeclared identifier 'm_prop1'; did you mean '_m_prop1'?}}
|
||||
}
|
||||
@end
|
||||
|
||||
// rdar://30310772
|
||||
|
||||
@interface InvalidNameInIvarAndPropertyBase
|
||||
{
|
||||
@public
|
||||
float _a;
|
||||
}
|
||||
@property float _b;
|
||||
@end
|
||||
|
||||
void invalidNameInIvarAndPropertyBase() {
|
||||
float a = ((InvalidNameInIvarAndPropertyBase*)node)->_a; // expected-error {{use of undeclared identifier 'node'}}
|
||||
float b = ((InvalidNameInIvarAndPropertyBase*)node)._b; // expected-error {{use of undeclared identifier 'node'}}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user