[help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

Kristóf Umann via cfe-dev
Hello everyone!
I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
```
ExplodedNode *N = C.generateNonFatalErrorNode();
  if (!N)
    return;
  auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
  R->addRange(binOp->getSourceRange());
  C.emitReport(std::move(R));
```

Below is the whole code of my project;
```
using namespace clang;
using namespace ento;


bool IsPureIntType(Expr *expr);
bool IsPureIntType(Expr *expr)
{
  if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
  {
    return true;
  }
  return false;
}

namespace
{

class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
{
  mutable std::unique_ptr<BugType> BT;

  public:
    IntegerAddOverFlowChecker();
    void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
  };
} // namespace

IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
    BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
}

void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
{
  if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
  {
    return;
  }

  if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
  {

    if (!IsPureIntType(binOp->getRHS()))
    {
      return;
    }

    if (!IsPureIntType(binOp->getLHS()))
    {
      return;
    }

    SVal RV = C.getSVal(binOp->getRHS());
    if (RV.isConstant())
    {
      return;
    }
  }
  else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
  {
    if (!IsPureIntType(binOp->getRHS()))
    {
      return;
    }

    if (!IsPureIntType(binOp->getLHS()))
    {
      return;
    }

    SVal LV = C.getSVal(binOp->getLHS());
    SVal RV = C.getSVal(binOp->getRHS());
    if (LV.isConstant() || RV.isConstant())
    {
      return;
    }
  }
  ExplodedNode *N = C.generateNonFatalErrorNode();
  if (!N)
    return;
  auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
  R->addRange(binOp->getSourceRange());
  C.emitReport(std::move(R));
}

extern "C" void clang_registerCheckers(CheckerRegistry &registry)
{
  registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
}

extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
```

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

Re: [help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

Kristóf Umann via cfe-dev
Hi,

Your code looks correct and i can't reproduce the problem that you're
describing. In particular, for me your checker warns on both lines of
the following sample code:


   void foo(int x, int y) {
     x + y;
     y + x;
   }


Here's how the output looks like for me:


   test.c:2:5: warning: two integer add may overflow
     x + y;
     ~~^~~
   test.c:3:5: warning: two integer add may overflow
     y + x;
     ~~^~~
   2 warnings generated.


What is your test case that you're having problems with?


On 9/4/19 9:02 PM, JunDong Xie via cfe-dev wrote:

> Hello everyone!
> I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
> ```
> ExplodedNode *N = C.generateNonFatalErrorNode();
>    if (!N)
>      return;
>    auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>    R->addRange(binOp->getSourceRange());
>    C.emitReport(std::move(R));
> ```
>
> Below is the whole code of my project;
> ```
> using namespace clang;
> using namespace ento;
>
>
> bool IsPureIntType(Expr *expr);
> bool IsPureIntType(Expr *expr)
> {
>    if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
>    {
>      return true;
>    }
>    return false;
> }
>
> namespace
> {
>
> class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
> {
>    mutable std::unique_ptr<BugType> BT;
>
>    public:
>      IntegerAddOverFlowChecker();
>      void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
>    };
> } // namespace
>
> IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
>      BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
> }
>
> void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
> {
>    if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
>    {
>      return;
>    }
>
>    if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
>    {
>
>      if (!IsPureIntType(binOp->getRHS()))
>      {
>        return;
>      }
>
>      if (!IsPureIntType(binOp->getLHS()))
>      {
>        return;
>      }
>
>      SVal RV = C.getSVal(binOp->getRHS());
>      if (RV.isConstant())
>      {
>        return;
>      }
>    }
>    else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
>    {
>      if (!IsPureIntType(binOp->getRHS()))
>      {
>        return;
>      }
>
>      if (!IsPureIntType(binOp->getLHS()))
>      {
>        return;
>      }
>
>      SVal LV = C.getSVal(binOp->getLHS());
>      SVal RV = C.getSVal(binOp->getRHS());
>      if (LV.isConstant() || RV.isConstant())
>      {
>        return;
>      }
>    }
>    ExplodedNode *N = C.generateNonFatalErrorNode();
>    if (!N)
>      return;
>    auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>    R->addRange(binOp->getSourceRange());
>    C.emitReport(std::move(R));
> }
>
> extern "C" void clang_registerCheckers(CheckerRegistry &registry)
> {
>    registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
> }
>
> extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
> ```
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

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

Re: [help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

Kristóf Umann via cfe-dev
+Kristof because he might know better, re-add cfe-dev because other
folks might know better.

One thing i didn't do exactly as JunDong was that i didn't use the
plugin interface but stuffed the checker directly into Clang instead.
Also i used recent master instead of release 8.0. This is completely
random but might this be a checker registration related issue that only
manifests with BuiltinBugs and the plugin interface and/or on older
versions of Clang?

JunDong, can you try to see if the issue remains if you put the checker
directly into Clang? Also, you did compile Clang from source anyway,
right? - you shouldn't be loading your plugin into a Clang built
elsewhere because there are no binary compatibility guarantees (i've no
idea what the actual consequences are though).

On 10.09.2019 19:21, JunDong Xie wrote:

> Thanks very much! I found that there is a problem in this line: `BT.reset(new BuiltinBug(this, "two integer add may overflow!"));`. if I change `BuiltinBug` into `BugType`, then the problem got solved.I am very curious why this problem can't be reproduced on your side. I use clang 8.0.0.
>
>
>> 在 2019年9月11日,上午2:52,Artem Dergachev <[hidden email]> 写道:
>>
>> Hi,
>>
>> Your code looks correct and i can't reproduce the problem that you're describing. In particular, for me your checker warns on both lines of the following sample code:
>>
>>
>>    void foo(int x, int y) {
>>      x + y;
>>      y + x;
>>    }
>>
>>
>> Here's how the output looks like for me:
>>
>>
>>    test.c:2:5: warning: two integer add may overflow
>>      x + y;
>>      ~~^~~
>>    test.c:3:5: warning: two integer add may overflow
>>      y + x;
>>      ~~^~~
>>    2 warnings generated.
>>
>>
>> What is your test case that you're having problems with?
>>
>>
>> On 9/4/19 9:02 PM, JunDong Xie via cfe-dev wrote:
>>> Hello everyone!
>>> I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
>>> ```
>>> ExplodedNode *N = C.generateNonFatalErrorNode();
>>>    if (!N)
>>>      return;
>>>    auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>    R->addRange(binOp->getSourceRange());
>>>    C.emitReport(std::move(R));
>>> ```
>>>
>>> Below is the whole code of my project;
>>> ```
>>> using namespace clang;
>>> using namespace ento;
>>>
>>>
>>> bool IsPureIntType(Expr *expr);
>>> bool IsPureIntType(Expr *expr)
>>> {
>>>    if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
>>>    {
>>>      return true;
>>>    }
>>>    return false;
>>> }
>>>
>>> namespace
>>> {
>>>
>>> class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
>>> {
>>>    mutable std::unique_ptr<BugType> BT;
>>>
>>>    public:
>>>      IntegerAddOverFlowChecker();
>>>      void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
>>>    };
>>> } // namespace
>>>
>>> IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
>>>      BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
>>> }
>>>
>>> void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
>>> {
>>>    if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
>>>    {
>>>      return;
>>>    }
>>>
>>>    if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
>>>    {
>>>
>>>      if (!IsPureIntType(binOp->getRHS()))
>>>      {
>>>        return;
>>>      }
>>>
>>>      if (!IsPureIntType(binOp->getLHS()))
>>>      {
>>>        return;
>>>      }
>>>
>>>      SVal RV = C.getSVal(binOp->getRHS());
>>>      if (RV.isConstant())
>>>      {
>>>        return;
>>>      }
>>>    }
>>>    else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
>>>    {
>>>      if (!IsPureIntType(binOp->getRHS()))
>>>      {
>>>        return;
>>>      }
>>>
>>>      if (!IsPureIntType(binOp->getLHS()))
>>>      {
>>>        return;
>>>      }
>>>
>>>      SVal LV = C.getSVal(binOp->getLHS());
>>>      SVal RV = C.getSVal(binOp->getRHS());
>>>      if (LV.isConstant() || RV.isConstant())
>>>      {
>>>        return;
>>>      }
>>>    }
>>>    ExplodedNode *N = C.generateNonFatalErrorNode();
>>>    if (!N)
>>>      return;
>>>    auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>    R->addRange(binOp->getSourceRange());
>>>    C.emitReport(std::move(R));
>>> }
>>>
>>> extern "C" void clang_registerCheckers(CheckerRegistry &registry)
>>> {
>>>    registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
>>> }
>>>
>>> extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
>>> ```
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> [hidden email]
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

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

Re: [help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

Kristóf Umann via cfe-dev
I tried to compile the checker directly into the clang source code, and the problem is solved. My previous practice was to download the pre-compiled version of clang called clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04, and then compile the checker into a plugin. I wrote the Cmake file with reference to the online tutorial. The contents of the Cmake file are as follows:
```
Cmake_minimum_required (VERSION 2.8)

Project (SimpleTestChecker)

Set(CMAKE_C_FLAGS "-g -D__GLIBCXX_USE_CXX11_ABI=0 -fno-rtti")
Set(CMAKE_CXX_FLAGS "-g -D__GLIBCXX_USE_CXX11_ABI=0 -fno-rtti")

Set(LLVM_DIR "../lib/cmake/llvm")

List(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
List(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}")

Find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR})
Message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
Message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

#find_package(Clang REQUIRED)

Message("LLVM STATUS:
  Definitions ${LLVM_DEFINITIONS}
  Includes ${LLVM_INCLUDE_DIRS}
              ${CLANG_INCLUDE_DIRS}
  Libraries ${LLVM_LIBRARY_DIRS}")

Add_definitions(${LLVM_DEFINITIONS})
Include_directories(${LLVM_INCLUDE_DIRS})
Link_directories(${LLVM_LIBRARY_DIRS})
 
Add_library(IntegerAddOverflowChecker SHARED
IntegerAddOverflowChecker.cpp
  )
 
Add_library(TaintChecker SHARED
GenericTaintChecker.cpp
  )

Add_library(SimpleTestChecker SHARED
SimpleTestChecker.cpp
  )
```

I don't know if it is because of an error in the CMake file.

> 在 2019年9月11日,下午12:24,Artem Dergachev <[hidden email]> 写道:
>
> +Kristof because he might know better, re-add cfe-dev because other folks might know better.
>
> One thing i didn't do exactly as JunDong was that i didn't use the plugin interface but stuffed the checker directly into Clang instead. Also i used recent master instead of release 8.0. This is completely random but might this be a checker registration related issue that only manifests with BuiltinBugs and the plugin interface and/or on older versions of Clang?
>
> JunDong, can you try to see if the issue remains if you put the checker directly into Clang? Also, you did compile Clang from source anyway, right? - you shouldn't be loading your plugin into a Clang built elsewhere because there are no binary compatibility guarantees (i've no idea what the actual consequences are though).
>
> On 10.09.2019 19:21, JunDong Xie wrote:
>> Thanks very much! I found that there is a problem in this line: `BT.reset(new BuiltinBug(this, "two integer add may overflow!"));`. if I change `BuiltinBug` into `BugType`, then the problem got solved.I am very curious why this problem can't be reproduced on your side. I use clang 8.0.0.
>>
>>
>>> 在 2019年9月11日,上午2:52,Artem Dergachev <[hidden email]> 写道:
>>>
>>> Hi,
>>>
>>> Your code looks correct and i can't reproduce the problem that you're describing. In particular, for me your checker warns on both lines of the following sample code:
>>>
>>>
>>>   void foo(int x, int y) {
>>>     x + y;
>>>     y + x;
>>>   }
>>>
>>>
>>> Here's how the output looks like for me:
>>>
>>>
>>>   test.c:2:5: warning: two integer add may overflow
>>>     x + y;
>>>     ~~^~~
>>>   test.c:3:5: warning: two integer add may overflow
>>>     y + x;
>>>     ~~^~~
>>>   2 warnings generated.
>>>
>>>
>>> What is your test case that you're having problems with?
>>>
>>>
>>> On 9/4/19 9:02 PM, JunDong Xie via cfe-dev wrote:
>>>> Hello everyone!
>>>> I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
>>>> ```
>>>> ExplodedNode *N = C.generateNonFatalErrorNode();
>>>>   if (!N)
>>>>     return;
>>>>   auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>>   R->addRange(binOp->getSourceRange());
>>>>   C.emitReport(std::move(R));
>>>> ```
>>>>
>>>> Below is the whole code of my project;
>>>> ```
>>>> using namespace clang;
>>>> using namespace ento;
>>>>
>>>>
>>>> bool IsPureIntType(Expr *expr);
>>>> bool IsPureIntType(Expr *expr)
>>>> {
>>>>   if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
>>>>   {
>>>>     return true;
>>>>   }
>>>>   return false;
>>>> }
>>>>
>>>> namespace
>>>> {
>>>>
>>>> class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
>>>> {
>>>>   mutable std::unique_ptr<BugType> BT;
>>>>
>>>>   public:
>>>>     IntegerAddOverFlowChecker();
>>>>     void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
>>>>   };
>>>> } // namespace
>>>>
>>>> IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
>>>>     BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
>>>> }
>>>>
>>>> void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
>>>> {
>>>>   if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
>>>>   {
>>>>     return;
>>>>   }
>>>>
>>>>   if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
>>>>   {
>>>>
>>>>     if (!IsPureIntType(binOp->getRHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     if (!IsPureIntType(binOp->getLHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     SVal RV = C.getSVal(binOp->getRHS());
>>>>     if (RV.isConstant())
>>>>     {
>>>>       return;
>>>>     }
>>>>   }
>>>>   else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
>>>>   {
>>>>     if (!IsPureIntType(binOp->getRHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     if (!IsPureIntType(binOp->getLHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     SVal LV = C.getSVal(binOp->getLHS());
>>>>     SVal RV = C.getSVal(binOp->getRHS());
>>>>     if (LV.isConstant() || RV.isConstant())
>>>>     {
>>>>       return;
>>>>     }
>>>>   }
>>>>   ExplodedNode *N = C.generateNonFatalErrorNode();
>>>>   if (!N)
>>>>     return;
>>>>   auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>>   R->addRange(binOp->getSourceRange());
>>>>   C.emitReport(std::move(R));
>>>> }
>>>>
>>>> extern "C" void clang_registerCheckers(CheckerRegistry &registry)
>>>> {
>>>>   registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
>>>> }
>>>>
>>>> extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
>>>> ```
>>>>
>>>> _______________________________________________
>>>> cfe-dev mailing list
>>>> [hidden email]
>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>

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

Re: [help wanted] Implemented a simple Clang Static Checker, but finished executing after only finding one bug

Kristóf Umann via cfe-dev
So it works when adding to clang, but not as a plugin? Wow, that's weird, I have no idea how that managed to happen. The fact that you used a prebuilt binary might cause issues (or not, never tried), though compiling with source and using this config might help: https://github.com/Szelethus/minimal_csa_plugin.

On Wed, 11 Sep 2019 at 09:36, JunDong Xie <[hidden email]> wrote:
I tried to compile the checker directly into the clang source code, and the problem is solved. My previous practice was to download the pre-compiled version of clang called clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04, and then compile the checker into a plugin. I wrote the Cmake file with reference to the online tutorial. The contents of the Cmake file are as follows:
```
Cmake_minimum_required (VERSION 2.8)

Project (SimpleTestChecker)

Set(CMAKE_C_FLAGS "-g -D__GLIBCXX_USE_CXX11_ABI=0 -fno-rtti")
Set(CMAKE_CXX_FLAGS "-g -D__GLIBCXX_USE_CXX11_ABI=0 -fno-rtti")

Set(LLVM_DIR "../lib/cmake/llvm")

List(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/")
List(APPEND CMAKE_MODULE_PATH "${LLVM_DIR}")

Find_package(LLVM REQUIRED CONFIG HINTS ${LLVM_DIR})
Message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
Message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")

#find_package(Clang REQUIRED)

Message("LLVM STATUS:
  Definitions ${LLVM_DEFINITIONS}
  Includes ${LLVM_INCLUDE_DIRS}
              ${CLANG_INCLUDE_DIRS}
  Libraries ${LLVM_LIBRARY_DIRS}")

Add_definitions(${LLVM_DEFINITIONS})
Include_directories(${LLVM_INCLUDE_DIRS})
Link_directories(${LLVM_LIBRARY_DIRS})

Add_library(IntegerAddOverflowChecker SHARED
IntegerAddOverflowChecker.cpp
  )

Add_library(TaintChecker SHARED
GenericTaintChecker.cpp
  )

Add_library(SimpleTestChecker SHARED
SimpleTestChecker.cpp
  )
```

I don't know if it is because of an error in the CMake file.

> 在 2019年9月11日,下午12:24,Artem Dergachev <[hidden email]> 写道:
>
> +Kristof because he might know better, re-add cfe-dev because other folks might know better.
>
> One thing i didn't do exactly as JunDong was that i didn't use the plugin interface but stuffed the checker directly into Clang instead. Also i used recent master instead of release 8.0. This is completely random but might this be a checker registration related issue that only manifests with BuiltinBugs and the plugin interface and/or on older versions of Clang?
>
> JunDong, can you try to see if the issue remains if you put the checker directly into Clang? Also, you did compile Clang from source anyway, right? - you shouldn't be loading your plugin into a Clang built elsewhere because there are no binary compatibility guarantees (i've no idea what the actual consequences are though).
>
> On 10.09.2019 19:21, JunDong Xie wrote:
>> Thanks very much! I found that there is a problem in this line: `BT.reset(new BuiltinBug(this, "two integer add may overflow!"));`. if I change `BuiltinBug` into `BugType`, then the problem got solved.I am very curious why this problem can't be reproduced on your side. I use clang 8.0.0.
>>
>>
>>> 在 2019年9月11日,上午2:52,Artem Dergachev <[hidden email]> 写道:
>>>
>>> Hi,
>>>
>>> Your code looks correct and i can't reproduce the problem that you're describing. In particular, for me your checker warns on both lines of the following sample code:
>>>
>>>
>>>   void foo(int x, int y) {
>>>     x + y;
>>>     y + x;
>>>   }
>>>
>>>
>>> Here's how the output looks like for me:
>>>
>>>
>>>   test.c:2:5: warning: two integer add may overflow
>>>     x + y;
>>>     ~~^~~
>>>   test.c:3:5: warning: two integer add may overflow
>>>     y + x;
>>>     ~~^~~
>>>   2 warnings generated.
>>>
>>>
>>> What is your test case that you're having problems with?
>>>
>>>
>>> On 9/4/19 9:02 PM, JunDong Xie via cfe-dev wrote:
>>>> Hello everyone!
>>>> I implemented a simple Clang static analysis checker to detect if there are two integer variables added in the program, because adding two integers may overflow. However, during the execution of the checker, it reports immediately to the user once it encounters the first bug, and then exits. I want it to continue to run and report all bugs. Refer to this link http://clang-analyzer.llvm.org/checker_dev_manual.html#links , I used the addTransition function to generate an ExplodedNode and pass it to the BugReport constructor, but it didn't work. I also tried the generateNonFatalErrorNode function and it didn't work too. Can someone help me to see where is the problem? Thanks very much! Below is the code related to my error report
>>>> ```
>>>> ExplodedNode *N = C.generateNonFatalErrorNode();
>>>>   if (!N)
>>>>     return;
>>>>   auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>>   R->addRange(binOp->getSourceRange());
>>>>   C.emitReport(std::move(R));
>>>> ```
>>>>
>>>> Below is the whole code of my project;
>>>> ```
>>>> using namespace clang;
>>>> using namespace ento;
>>>>
>>>>
>>>> bool IsPureIntType(Expr *expr);
>>>> bool IsPureIntType(Expr *expr)
>>>> {
>>>>   if (expr->getType()->isIntegerType() && !expr->getType()->isEnumeralType() && !expr->getType()->isBooleanType())
>>>>   {
>>>>     return true;
>>>>   }
>>>>   return false;
>>>> }
>>>>
>>>> namespace
>>>> {
>>>>
>>>> class IntegerAddOverFlowChecker : public Checker<check::PreStmt<BinaryOperator>>
>>>> {
>>>>   mutable std::unique_ptr<BugType> BT;
>>>>
>>>>   public:
>>>>     IntegerAddOverFlowChecker();
>>>>     void checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const;
>>>>   };
>>>> } // namespace
>>>>
>>>> IntegerAddOverFlowChecker::IntegerAddOverFlowChecker() {
>>>>     BT.reset(new BuiltinBug(this, "two integer add may overflow!"));
>>>> }
>>>>
>>>> void IntegerAddOverFlowChecker::checkPreStmt(const BinaryOperator *binOp, CheckerContext &C) const
>>>> {
>>>>   if (binOp->getOpcode() != BinaryOperatorKind::BO_AddAssign && binOp->getOpcode() != BinaryOperatorKind::BO_Add)
>>>>   {
>>>>     return;
>>>>   }
>>>>
>>>>   if (binOp->getOpcode() == BinaryOperatorKind::BO_AddAssign)
>>>>   {
>>>>
>>>>     if (!IsPureIntType(binOp->getRHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     if (!IsPureIntType(binOp->getLHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     SVal RV = C.getSVal(binOp->getRHS());
>>>>     if (RV.isConstant())
>>>>     {
>>>>       return;
>>>>     }
>>>>   }
>>>>   else if (binOp->getOpcode() == BinaryOperatorKind::BO_Add)
>>>>   {
>>>>     if (!IsPureIntType(binOp->getRHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     if (!IsPureIntType(binOp->getLHS()))
>>>>     {
>>>>       return;
>>>>     }
>>>>
>>>>     SVal LV = C.getSVal(binOp->getLHS());
>>>>     SVal RV = C.getSVal(binOp->getRHS());
>>>>     if (LV.isConstant() || RV.isConstant())
>>>>     {
>>>>       return;
>>>>     }
>>>>   }
>>>>   ExplodedNode *N = C.generateNonFatalErrorNode();
>>>>   if (!N)
>>>>     return;
>>>>   auto R = std::make_unique<BugReport>(*BT, BT->getName(), N);
>>>>   R->addRange(binOp->getSourceRange());
>>>>   C.emitReport(std::move(R));
>>>> }
>>>>
>>>> extern "C" void clang_registerCheckers(CheckerRegistry &registry)
>>>> {
>>>>   registry.addChecker<IntegerAddOverFlowChecker>("alpha.core.IntegerAddOverFlowChecker", "Checks for two integer add may cause overflow", "NULL");
>>>> }
>>>>
>>>> extern "C" const char clang_analyzerAPIVersionString[] = CLANG_ANALYZER_API_VERSION_STRING;
>>>> ```
>>>>
>>>> _______________________________________________
>>>> cfe-dev mailing list
>>>> [hidden email]
>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>


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