RetainCountChecker | Assertion Failure | check-clang-analysis

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RetainCountChecker | Assertion Failure | check-clang-analysis

Xin Wang via cfe-dev
Dear all,

I am currently trying to suppress diagnostics emitted if the function under consideration has a certain annotate attribute ("check_attribute_annotate" in this case).

Hence, for that, I added the following piece of code to RetainCountChecker.cpp but it is resulting in some assertion failures while performing make -j4 check-clang-analysis.



diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 89b1291..9f367be 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1894,6 +1894,20 @@ static bool isSynthesizedAccessor(const StackFrameContext *SFC) {
   return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
 }
 
+bool
+isAnnotatedToSkipDiagnostics(const ExplodedNode *EN) {
+  const FunctionDecl *FD = cast<FunctionDecl>(&EN->getCodeDecl());
+  const IdentifierInfo *II = FD->getIdentifier();
+
+  if (II) {
+    for (const auto *Ann : FD->specific_attrs<AnnotateAttr>()){
+      if (Ann->getAnnotation() == "check_attribute_annotate")
+        return true;
+    }
+  }
+  return false;
+}
+
 std::shared_ptr<PathDiagnosticPiece>
 CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN,
                               BugReporterContext &BRC, BugReport &BR) {
@@ -3345,11 +3359,13 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
   }
 
   assert(BT);
-  auto report = std::unique_ptr<BugReport>(
-      new CFRefReport(*BT, C.getASTContext().getLangOpts(), C.isObjCGCEnabled(),
-                      SummaryLog, N, Sym));
-  report->addRange(ErrorRange);
-  C.emitReport(std::move(report));
+  if (!isAnnotatedToSkipDiagnostics(N)){
+    auto report = std::unique_ptr<BugReport>(
+        new CFRefReport(*BT, C.getASTContext().getLangOpts(), C.isObjCGCEnabled(),
+                        SummaryLog, N, Sym));
+    report->addRange(ErrorRange);
+    C.emitReport(std::move(report));
+  }
 }
 
 //===----------------------------------------------------------------------===//

More specifically, the code highlighted in red above is causing the two assertion failures mentioned below.

The following test-cases are the unexpected failures:
  • Analysis/inlining/RetainCountExamples.m
  • Analysis/properties.m
Note: The above diff is a subset of the code that I have changed. I added the check if (!isAnnotatedToSkipDiagnostics(N)) before every invocation to emitReport to suppress raising warnings for functions having the annotate attribute check_attribute_annotate. It seemed to work for manually made test-cases but clearly there is something wrong with my methodology.


Could anyone please tell me the reason behind these assertion failures?


Thank you.


Regards,
Malhar Thakkar

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RetainCountChecker | Assertion Failure | check-clang-analysis

Xin Wang via cfe-dev
Uhm, why does this thing return `const Decl &` rather than `const Decl
*`? Anyway, whatever, never mind.


You're crashing in...

   cast<FunctionDecl>(&EN->getCodeDecl())

...because this Decl returned by `EN->getCodeDecl()` isn't a FunctionDecl.


You can easily see this from the backtrace:

Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible
type!"), function cast, file
(...censored...)/llvm/include/llvm/Support/Casting.h, line 254.
0  libLLVMSupport.dylib                 0x00000001148fb8fc
llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
1  libLLVMSupport.dylib                 0x00000001148fbec9
PrintStackTraceSignalHandler(void*) + 25
2  libLLVMSupport.dylib                 0x00000001148f7b59
llvm::sys::RunSignalHandlers() + 425
3  libLLVMSupport.dylib                 0x00000001148fc212
SignalHandler(int) + 354
4  libsystem_platform.dylib             0x00007fffd872cb3a _sigtramp + 26
5  libclangStaticAnalyzerCore.dylib     0x0000000122060c7b
llvm::alignAddr(void const*, unsigned long) + 43
6  libsystem_c.dylib                    0x00007fffd85b1420 abort + 129
7  libsystem_c.dylib                    0x00007fffd8578893 basename_r + 0
8  libclangStaticAnalyzerCheckers.dylib 0x00000001202e6fe7
llvm::cast_retty<clang::FunctionDecl, clang::Decl const*>::ret_type
llvm::cast<clang::FunctionDecl, clang::Decl const>(clang::Decl const*) + 103
9  libclangStaticAnalyzerCheckers.dylib 0x00000001208b7aa6
isAnnotatedToSkipDiagnostics(clang::ento::ExplodedNode const*) + 38
(...more stuff...)

You're calling llvm::cast<> (frame 8) from your new function (frame 9),
the only cast you have is `cast<FunctionDecl>(&EN->getCodeDecl())`, and
the assertion message says that the argument is of incompatible type.


If you want to know what specific decl causes a problem, you can print
it in the debugger:

$ lldb -- (...censored...)/debug/./bin/clang -cc1 -internal-isystem
(...censored...)/debug/lib/clang/5.0.0/include -nostdsysteminc -analyze
-analyzer-constraints=range
-analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection
-analyzer-store=region -verify -Wno-objc-root-class
(...censored...)/llvm/tools/clang/test/Analysis/properties.m

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
     frame #0: 0x00007fffd864bd42 libsystem_kernel.dylib`__pthread_kill + 10
     frame #1: 0x00007fffd8739787 libsystem_pthread.dylib`pthread_kill + 90
     frame #2: 0x00007fffd85b1420 libsystem_c.dylib`abort + 129
     frame #3: 0x00007fffd8578893 libsystem_c.dylib`__assert_rtn + 320
     frame #4: 0x0000000114983fe7
libclangStaticAnalyzerCheckers.dylib`llvm::cast_retty<clang::FunctionDecl,
clang::Decl const*>::ret_type llvm::cast<clang::FunctionDecl,
clang::Decl const>(Val=0x00000001170ab5c0) at Casting.h:254
   * frame #5: 0x0000000114f54aa6
libclangStaticAnalyzerCheckers.dylib`isAnnotatedToSkipDiagnostics(EN=0x0000000118815ee0)
at RetainCountChecker.cpp:1904
(...more stuff...)

(lldb) f 5
frame #5: 0x0000000114f54aa6
libclangStaticAnalyzerCheckers.dylib`isAnnotatedToSkipDiagnostics(EN=0x0000000118815ee0)
at RetainCountChecker.cpp:1904
    1901
    1902    bool
    1903    isAnnotatedToSkipDiagnostics(const ExplodedNode *EN) {
-> 1904      const FunctionDecl *FD =
cast<FunctionDecl>(&EN->getCodeDecl());
    1905      const IdentifierInfo *II = FD->getIdentifier();
    1906
    1907      if (II) {

(lldb) p EN->getCodeDecl().dump()
ObjCMethodDecl 0x1170ab5c0
<(...censored...)/llvm/tools/clang/test/Analysis/properties.m:559:1,
line:563:1> line:559:1 - testRetainAndRelease 'void'
(...more stuff...)

Note that frames are shifted in the debugger because it stops on the
moment when the assertion has failed, so we're on frame 5 instead of
frame 9 now.

If you use gdb instead of lldb, just replace "lldb --" with "gdb --args"
in the first command, the rest is the same. If you use an IDE, then you
should know better how to debug this.


So in this case it's ObjCMethodDecl, and Objective-C methods apparently
aren't functions. I'd also worry about BlockDecl which may also appear here.

You should use dyn_cast<> when you're not sure if the cast succeeds -
it'd return nullptr instead of crashing, and you can handle it.


On 7/1/17 10:12 AM, Malhar Thakkar via cfe-dev wrote:

> Dear all,
>
> I am currently trying to suppress diagnostics emitted if the function
> under consideration has a certain annotate attribute
> ("check_attribute_annotate" in this case).
>
> Hence, for that, I added the following piece of code to
> RetainCountChecker.cpp but it is resulting in some assertion failures
> while performing make -j4 check-clang-analysis.
>
>
>
> diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> index 89b1291..9f367be 100644
> --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
> @@ -1894,6 +1894,20 @@ static bool isSynthesizedAccessor(const
> StackFrameContext *SFC) {
> return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
>  }
> +bool
> +isAnnotatedToSkipDiagnostics(const ExplodedNode *EN) {
> + const FunctionDecl *FD = cast<FunctionDecl>(&EN->getCodeDecl());
> + const IdentifierInfo *II = FD->getIdentifier();
> +
> + if (II) {
> + for (const auto *Ann : FD->specific_attrs<AnnotateAttr>()){
> + if (Ann->getAnnotation() == "check_attribute_annotate")
> + return true;
> +    }
> +  }
> + return false;
> +}
> +
>  std::shared_ptr<PathDiagnosticPiece>
>  CFRefReportVisitor::VisitNode(const ExplodedNode *N, const
> ExplodedNode *PrevN,
>            BugReporterContext &BRC, BugReport &BR) {
> @@ -3345,11 +3359,13 @@ void
> RetainCountChecker::processNonLeakError(ProgramStateRef St,
>    }
>    assert(BT);
> -  auto report = std::unique_ptr<BugReport>(
> - new CFRefReport(*BT, C.getASTContext().getLangOpts(),
> C.isObjCGCEnabled(),
> -    SummaryLog, N, Sym));
> -  report->addRange(ErrorRange);
> -  C.emitReport(std::move(report));
> + if (!isAnnotatedToSkipDiagnostics(N)){
> +  auto report = std::unique_ptr<BugReport>(
> + new CFRefReport(*BT, C.getASTContext().getLangOpts(),
> C.isObjCGCEnabled(),
> +                      SummaryLog, N, Sym));
> +  report->addRange(ErrorRange);
> +  C.emitReport(std::move(report));
> +  }
>  }
> //===----------------------------------------------------------------------===//
>
> More specifically, the code highlighted in red above is causing the
> two assertion failures mentioned below.
>
> The following test-cases are the unexpected failures:
>
>   * Analysis/inlining/RetainCountExamples.m
>   * Analysis/properties.m
>
> *Note:* The above diff is a subset of the code that I have changed. I
> added the check *if (!isAnnotatedToSkipDiagnostics(N))* before every
> invocation to *emitReport* to suppress raising warnings for functions
> having the annotate attribute *check_attribute_annotate*. It seemed to
> work for manually made test-cases but clearly there is something wrong
> with my methodology.
>
>
> Could anyone please tell me the reason behind these assertion failures?
>
>
> Thank you.
>
>
> Regards,
> Malhar Thakkar
> ᐧ
>
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: RetainCountChecker | Assertion Failure | check-clang-analysis

Xin Wang via cfe-dev


On Sun, Jul 2, 2017 at 12:40 PM, Artem Dergachev <[hidden email]> wrote:
Uhm, why does this thing return `const Decl &` rather than `const Decl *`? Anyway, whatever, never mind.


You're crashing in...

  cast<FunctionDecl>(&EN->getCodeDecl())

...because this Decl returned by `EN->getCodeDecl()` isn't a FunctionDecl.


You can easily see this from the backtrace:

Assertion failed: (isa<X>(Val) && "cast<Ty>() argument of incompatible type!"), function cast, file (...censored...)/llvm/include/llvm/Support/Casting.h, line 254.
0  libLLVMSupport.dylib                 0x00000001148fb8fc llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 60
1  libLLVMSupport.dylib                 0x00000001148fbec9 PrintStackTraceSignalHandler(void*) + 25
2  libLLVMSupport.dylib                 0x00000001148f7b59 llvm::sys::RunSignalHandlers() + 425
3  libLLVMSupport.dylib                 0x00000001148fc212 SignalHandler(int) + 354
4  libsystem_platform.dylib             0x00007fffd872cb3a _sigtramp + 26
5  libclangStaticAnalyzerCore.dylib     0x0000000122060c7b llvm::alignAddr(void const*, unsigned long) + 43
6  libsystem_c.dylib                    0x00007fffd85b1420 abort + 129
7  libsystem_c.dylib                    0x00007fffd8578893 basename_r + 0
8  libclangStaticAnalyzerCheckers.dylib 0x00000001202e6fe7 llvm::cast_retty<clang::FunctionDecl, clang::Decl const*>::ret_type llvm::cast<clang::FunctionDecl, clang::Decl const>(clang::Decl const*) + 103
9  libclangStaticAnalyzerCheckers.dylib 0x00000001208b7aa6 isAnnotatedToSkipDiagnostics(clang::ento::ExplodedNode const*) + 38
(...more stuff...)

You're calling llvm::cast<> (frame 8) from your new function (frame 9), the only cast you have is `cast<FunctionDecl>(&EN->getCodeDecl())`, and the assertion message says that the argument is of incompatible type.


If you want to know what specific decl causes a problem, you can print it in the debugger:

$ lldb -- (...censored...)/debug/./bin/clang -cc1 -internal-isystem (...censored...)/debug/lib/clang/5.0.0/include -nostdsysteminc -analyze -analyzer-constraints=range -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class (...censored...)/llvm/tools/clang/test/Analysis/properties.m

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fffd864bd42 libsystem_kernel.dylib`__pthread_kill + 10
    frame #1: 0x00007fffd8739787 libsystem_pthread.dylib`pthread_kill + 90
    frame #2: 0x00007fffd85b1420 libsystem_c.dylib`abort + 129
    frame #3: 0x00007fffd8578893 libsystem_c.dylib`__assert_rtn + 320
    frame #4: 0x0000000114983fe7 libclangStaticAnalyzerCheckers.dylib`llvm::cast_retty<clang::FunctionDecl, clang::Decl const*>::ret_type llvm::cast<clang::FunctionDecl, clang::Decl const>(Val=0x00000001170ab5c0) at Casting.h:254
  * frame #5: 0x0000000114f54aa6 libclangStaticAnalyzerCheckers.dylib`isAnnotatedToSkipDiagnostics(EN=0x0000000118815ee0) at RetainCountChecker.cpp:1904
(...more stuff...)

(lldb) f 5
frame #5: 0x0000000114f54aa6 libclangStaticAnalyzerCheckers.dylib`isAnnotatedToSkipDiagnostics(EN=0x0000000118815ee0) at RetainCountChecker.cpp:1904
   1901
   1902    bool
   1903    isAnnotatedToSkipDiagnostics(const ExplodedNode *EN) {
-> 1904      const FunctionDecl *FD = cast<FunctionDecl>(&EN->getCodeDecl());
   1905      const IdentifierInfo *II = FD->getIdentifier();
   1906
   1907      if (II) {

(lldb) p EN->getCodeDecl().dump()
ObjCMethodDecl 0x1170ab5c0 <(...censored...)/llvm/tools/clang/test/Analysis/properties.m:559:1, line:563:1> line:559:1 - testRetainAndRelease 'void'
(...more stuff...)

Thanks a ton for this, Dr. Artem. This really helped. 

Note that frames are shifted in the debugger because it stops on the moment when the assertion has failed, so we're on frame 5 instead of frame 9 now.

If you use gdb instead of lldb, just replace "lldb --" with "gdb --args" in the first command, the rest is the same. If you use an IDE, then you should know better how to debug this.


So in this case it's ObjCMethodDecl, and Objective-C methods apparently aren't functions. I'd also worry about BlockDecl which may also appear here.

You should use dyn_cast<> when you're not sure if the cast succeeds - it'd return nullptr instead of crashing, and you can handle it.
Okay, I'll try using dyn_cast<>. 



On 7/1/17 10:12 AM, Malhar Thakkar via cfe-dev wrote:
Dear all,

I am currently trying to suppress diagnostics emitted if the function under consideration has a certain annotate attribute ("check_attribute_annotate" in this case).

Hence, for that, I added the following piece of code to RetainCountChecker.cpp but it is resulting in some assertion failures while performing make -j4 check-clang-analysis.



diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 89b1291..9f367be 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1894,6 +1894,20 @@ static bool isSynthesizedAccessor(const StackFrameContext *SFC) {
return SFC->getAnalysisDeclContext()->isBodyAutosynthesized();
 }
+bool
+isAnnotatedToSkipDiagnostics(const ExplodedNode *EN) {
+ const FunctionDecl *FD = cast<FunctionDecl>(&EN->getCodeDecl());
+ const IdentifierInfo *II = FD->getIdentifier();
+
+ if (II) {
+ for (const auto *Ann : FD->specific_attrs<AnnotateAttr>()){
+ if (Ann->getAnnotation() == "check_attribute_annotate")
+ return true;
+    }
+  }
+ return false;
+}
+
 std::shared_ptr<PathDiagnosticPiece>
 CFRefReportVisitor::VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN,
           BugReporterContext &BRC, BugReport &BR) {
@@ -3345,11 +3359,13 @@ void RetainCountChecker::processNonLeakError(ProgramStateRef St,
   }
   assert(BT);
-  auto report = std::unique_ptr<BugReport>(
- new CFRefReport(*BT, C.getASTContext().getLangOpts(), C.isObjCGCEnabled(),
-    SummaryLog, N, Sym));
-  report->addRange(ErrorRange);
-  C.emitReport(std::move(report));
+ if (!isAnnotatedToSkipDiagnostics(N)){
+  auto report = std::unique_ptr<BugReport>(
+ new CFRefReport(*BT, C.getASTContext().getLangOpts(), C.isObjCGCEnabled(),
+                      SummaryLog, N, Sym));
+  report->addRange(ErrorRange);
+  C.emitReport(std::move(report));
+  }
 }
//===----------------------------------------------------------------------===//

More specifically, the code highlighted in red above is causing the two assertion failures mentioned below.

The following test-cases are the unexpected failures:

  * Analysis/inlining/RetainCountExamples.m
  * Analysis/properties.m

*Note:* The above diff is a subset of the code that I have changed. I added the check *if (!isAnnotatedToSkipDiagnostics(N))* before every invocation to *emitReport* to suppress raising warnings for functions having the annotate attribute *check_attribute_annotate*. It seemed to work for manually made test-cases but clearly there is something wrong with my methodology.


Could anyone please tell me the reason behind these assertion failures?


Thank you.


Regards,
Malhar Thakkar



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Loading...