Skip to content

Commit

Permalink
Merged master:a45fb1942fc into amd-gfx:313eb908304
Browse files Browse the repository at this point in the history
Local branch amd-gfx 313eb90 Merged master:fe1a3a7e8c8 into amd-gfx:1c924b1df42
Remote branch master a45fb19 [mlir][Affine] Introduce affine memory interfaces
  • Loading branch information
Sw authored and Sw committed May 20, 2020
2 parents 313eb90 + a45fb19 commit da500a2
Show file tree
Hide file tree
Showing 19 changed files with 566 additions and 407 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,16 @@ class BuiltinBug : public BugType {
const char *description)
: BugType(checker, name, categories::LogicError), desc(description) {}

BuiltinBug(class CheckerNameRef checker, const char *name)
: BugType(checker, name, categories::LogicError), desc(name) {}

BuiltinBug(const CheckerBase *checker, const char *name)
: BugType(checker, name, categories::LogicError), desc(name) {}

StringRef getDescription() const { return desc; }
};

} // end ento namespace
} // namespace ento

} // end clang namespace
#endif
411 changes: 227 additions & 184 deletions clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Large diffs are not rendered by default.

24 changes: 14 additions & 10 deletions clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class StackAddrEscapeChecker
};

DefaultBool ChecksEnabled[CK_NumCheckKinds];
CheckerNameRef CheckNames[CK_NumCheckKinds];

void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPreStmt(const ReturnStmt *RS, CheckerContext &C) const;
Expand Down Expand Up @@ -156,7 +157,8 @@ void StackAddrEscapeChecker::EmitStackError(CheckerContext &C,
return;
if (!BT_returnstack)
BT_returnstack = std::make_unique<BuiltinBug>(
this, "Return of address to stack-allocated memory");
CheckNames[CK_StackAddrEscapeChecker],
"Return of address to stack-allocated memory");
// Generate a report for this bug.
SmallString<128> buf;
llvm::raw_svector_ostream os(buf);
Expand Down Expand Up @@ -195,7 +197,8 @@ void StackAddrEscapeChecker::checkAsyncExecutedBlockCaptures(
continue;
if (!BT_capturedstackasync)
BT_capturedstackasync = std::make_unique<BuiltinBug>(
this, "Address of stack-allocated memory is captured");
CheckNames[CK_StackAddrAsyncEscapeChecker],
"Address of stack-allocated memory is captured");
SmallString<128> Buf;
llvm::raw_svector_ostream Out(Buf);
SourceRange Range = genName(Out, Region, C.getASTContext());
Expand All @@ -218,7 +221,8 @@ void StackAddrEscapeChecker::checkReturnedBlockCaptures(
continue;
if (!BT_capturedstackret)
BT_capturedstackret = std::make_unique<BuiltinBug>(
this, "Address of stack-allocated memory is captured");
CheckNames[CK_StackAddrEscapeChecker],
"Address of stack-allocated memory is captured");
SmallString<128> Buf;
llvm::raw_svector_ostream Out(Buf);
SourceRange Range = genName(Out, Region, C.getASTContext());
Expand Down Expand Up @@ -277,7 +281,7 @@ void StackAddrEscapeChecker::checkPreStmt(const ReturnStmt *RS,

// The CK_CopyAndAutoreleaseBlockObject cast causes the block to be copied
// so the stack address is not escaping here.
if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetE)) {
if (const auto *ICE = dyn_cast<ImplicitCastExpr>(RetE)) {
if (isa<BlockDataRegion>(R) &&
ICE->getCastKind() == CK_CopyAndAutoreleaseBlockObject) {
return;
Expand Down Expand Up @@ -333,7 +337,8 @@ void StackAddrEscapeChecker::checkEndFunction(const ReturnStmt *RS,

if (!BT_stackleak)
BT_stackleak = std::make_unique<BuiltinBug>(
this, "Stack address stored into global variable",
CheckNames[CK_StackAddrEscapeChecker],
"Stack address stored into global variable",
"Stack address was saved into a global variable. "
"This is dangerous because the address will become "
"invalid after returning from the function");
Expand Down Expand Up @@ -371,14 +376,13 @@ bool ento::shouldRegisterStackAddrEscapeBase(const CheckerManager &mgr) {

#define REGISTER_CHECKER(name) \
void ento::register##name(CheckerManager &Mgr) { \
StackAddrEscapeChecker *Chk = \
Mgr.getChecker<StackAddrEscapeChecker>(); \
StackAddrEscapeChecker *Chk = Mgr.getChecker<StackAddrEscapeChecker>(); \
Chk->ChecksEnabled[StackAddrEscapeChecker::CK_##name] = true; \
Chk->CheckNames[StackAddrEscapeChecker::CK_##name] = \
Mgr.getCurrentCheckerName(); \
} \
\
bool ento::shouldRegister##name(const CheckerManager &mgr) { \
return true; \
}
bool ento::shouldRegister##name(const CheckerManager &mgr) { return true; }

REGISTER_CHECKER(StackAddrEscapeChecker)
REGISTER_CHECKER(StackAddrAsyncEscapeChecker)
9 changes: 8 additions & 1 deletion clang/test/Analysis/incorrect-checker-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,16 @@
int* stack_addr_escape_base() {
int x = 0;
// FIXME: This shouldn't be tied to a modeling checker.
return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller [core.StackAddrEscapeBase]}}
return &x; // expected-warning{{Address of stack memory associated with local variable 'x' returned to caller [core.StackAddressEscape]}}
// expected-note-re@-1{{{{^Address of stack memory associated with local variable 'x' returned to caller$}}}}
// Just a regular compiler warning.
// expected-warning@-3{{address of stack memory associated with local variable 'x' returned}}
}

char const *p;

void f0() {
char const str[] = "This will change";
p = str;
} // expected-warning{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference [core.StackAddressEscape]}}
// expected-note@-1{{Address of stack memory associated with local variable 'str' is still referred to by the global variable 'p' upon returning to the caller. This will be a dangling reference}}
32 changes: 31 additions & 1 deletion clang/test/Analysis/incorrect-checker-names.mm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clang_analyze_cc1 -fblocks -verify %s -Wno-objc-root-class \
// RUN: %clang_analyze_cc1 -fblocks -fobjc-arc -verify %s -Wno-objc-root-class \
// RUN: -analyzer-checker=core \
// RUN: -analyzer-checker=alpha.core.StackAddressAsyncEscape \
// RUN: -analyzer-checker=nullability \
// RUN: -analyzer-checker=osx

Expand Down Expand Up @@ -126,3 +127,32 @@ void use_out_param_leak() {
// FIXME: This shouldn't be tied to a modeling checker.
write_into_out_param_on_success(&obj); // expected-warning{{Potential leak of an object stored into 'obj' [osx.cocoa.RetainCountBase]}}
}

typedef struct dispatch_queue_s *dispatch_queue_t;
typedef void (^dispatch_block_t)(void);
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
typedef long dispatch_once_t;
void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
typedef long dispatch_time_t;
void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);

extern dispatch_queue_t queue;
extern dispatch_once_t *predicate;
extern dispatch_time_t when;

dispatch_block_t get_leaking_block() {
int leaked_x = 791;
int *p = &leaked_x;
return ^void(void) {
*p = 1;
};
// expected-warning@-3 {{Address of stack memory associated with local variable 'leaked_x' \
is captured by a returned block [core.StackAddressEscape]}}
}

void test_returned_from_func_block_async() {
dispatch_async(queue, get_leaking_block());
// expected-warning@-1 {{Address of stack memory associated with local variable 'leaked_x' \
is captured by an asynchronously-executed block [alpha.core.StackAddressAsyncEscape]}}
}
12 changes: 6 additions & 6 deletions libcxx/include/functional
Original file line number Diff line number Diff line change
Expand Up @@ -2338,14 +2338,14 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>

template <class _Fp, bool = _And<
_IsNotSame<__uncvref_t<_Fp>, function>,
__invokable<_Fp&, _ArgTypes...>
__invokable<_Fp, _ArgTypes...>
>::value>
struct __callable;
template <class _Fp>
struct __callable<_Fp, true>
{
static const bool value = is_same<void, _Rp>::value ||
is_convertible<typename __invoke_of<_Fp&, _ArgTypes...>::type,
is_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type,
_Rp>::value;
};
template <class _Fp>
Expand All @@ -2355,7 +2355,7 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)>
};

template <class _Fp>
using _EnableIfCallable = typename enable_if<__callable<_Fp>::value>::type;
using _EnableIfLValueCallable = typename enable_if<__callable<_Fp&>::value>::type;
public:
typedef _Rp result_type;

Expand All @@ -2366,7 +2366,7 @@ public:
function(nullptr_t) _NOEXCEPT {}
function(const function&);
function(function&&) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<_Fp>>
template<class _Fp, class = _EnableIfLValueCallable<_Fp>>
function(_Fp);

#if _LIBCPP_STD_VER <= 14
Expand All @@ -2380,14 +2380,14 @@ public:
function(allocator_arg_t, const _Alloc&, const function&);
template<class _Alloc>
function(allocator_arg_t, const _Alloc&, function&&);
template<class _Fp, class _Alloc, class = _EnableIfCallable<_Fp>>
template<class _Fp, class _Alloc, class = _EnableIfLValueCallable<_Fp>>
function(allocator_arg_t, const _Alloc& __a, _Fp __f);
#endif

function& operator=(const function&);
function& operator=(function&&) _NOEXCEPT;
function& operator=(nullptr_t) _NOEXCEPT;
template<class _Fp, class = _EnableIfCallable<typename decay<_Fp>::type>>
template<class _Fp, class = _EnableIfLValueCallable<typename decay<_Fp>::type>>
function& operator=(_Fp&&);

~function();
Expand Down
114 changes: 1 addition & 113 deletions libcxx/include/memory
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,6 @@ struct __allocator_traits_rebind
_LIBCPP_SUPPRESS_DEPRECATED_POP
};

#ifndef _LIBCPP_HAS_NO_VARIADICS

template <template <class, class...> class _Alloc, class _Tp, class ..._Args, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, true>
{
Expand All @@ -1322,62 +1320,6 @@ struct __allocator_traits_rebind<_Alloc<_Tp, _Args...>, _Up, false>
typedef _LIBCPP_NODEBUG_TYPE _Alloc<_Up, _Args...> type;
};

#else // _LIBCPP_HAS_NO_VARIADICS

template <template <class> class _Alloc, class _Tp, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, true>
{
typedef typename _Alloc<_Tp>::template rebind<_Up>::other type;
};

template <template <class> class _Alloc, class _Tp, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp>, _Up, false>
{
typedef _Alloc<_Up> type;
};

template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0>::template rebind<_Up>::other type;
};

template <template <class, class> class _Alloc, class _Tp, class _A0, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0>, _Up, false>
{
typedef _Alloc<_Up, _A0> type;
};

template <template <class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0, _A1>::template rebind<_Up>::other type;
};

template <template <class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1>, _Up, false>
{
typedef _Alloc<_Up, _A0, _A1> type;
};

template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _A2, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, true>
{
typedef typename _Alloc<_Tp, _A0, _A1, _A2>::template rebind<_Up>::other type;
};

template <template <class, class, class, class> class _Alloc, class _Tp, class _A0,
class _A1, class _A2, class _Up>
struct __allocator_traits_rebind<_Alloc<_Tp, _A0, _A1, _A2>, _Up, false>
{
typedef _Alloc<_Up, _A0, _A1, _A2> type;
};

#endif // _LIBCPP_HAS_NO_VARIADICS

#ifndef _LIBCPP_CXX03_LANG

_LIBCPP_SUPPRESS_DEPRECATED_PUSH
Expand Down Expand Up @@ -1920,67 +1862,13 @@ public:
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY size_type max_size() const _NOEXCEPT
{return size_type(~0) / sizeof(_Tp);}

#if !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
template <class _Up, class... _Args>
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY
void
construct(_Up* __p, _Args&&... __args)
{
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
}
#else // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p)
{
::new((void*)__p) _Tp();
}
# if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)

template <class _A0>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0)
{
::new((void*)__p) _Tp(__a0);
}
template <class _A0>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0)
{
::new((void*)__p) _Tp(__a0);
}
# endif // defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0, _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, _A0& __a0, const _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
template <class _A0, class _A1>
_LIBCPP_INLINE_VISIBILITY
void
construct(pointer __p, const _A0& __a0, const _A1& __a1)
{
::new((void*)__p) _Tp(__a0, __a1);
}
#endif // !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) && !defined(_LIBCPP_HAS_NO_VARIADICS)
_LIBCPP_DEPRECATED_IN_CXX17 _LIBCPP_INLINE_VISIBILITY void destroy(pointer __p) {__p->~_Tp();}
#endif
};
Expand Down Expand Up @@ -3954,7 +3842,7 @@ public:

template<class _Yp, class _CntrlBlk>
static shared_ptr<_Tp>
__create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl)
__create_with_control_block(_Yp* __p, _CntrlBlk* __cntrl) _NOEXCEPT
{
shared_ptr<_Tp> __r;
__r.__ptr_ = __p;
Expand Down
24 changes: 24 additions & 0 deletions mlir/include/mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===- AffineMemoryOpInterfaces.h -------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a set of interfaces for affine memory ops.
//
//===----------------------------------------------------------------------===//

#ifndef MLIR_INTERFACES_AFFINEMEMORYOPINTERFACES_H_
#define MLIR_INTERFACES_AFFINEMEMORYOPINTERFACES_H_

#include "mlir/IR/AffineMap.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/StandardTypes.h"

namespace mlir {
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h.inc"
} // namespace mlir

#endif // MLIR_INTERFACES_AFFINEMEMORYOPINTERFACES_H_
Loading

0 comments on commit da500a2

Please sign in to comment.