<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/62663>62663</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Taint not being applied across class heirarchies
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          tomrittervg
      </td>
    </tr>
</table>

<pre>
    I've found a few places where the Static Analysis Engine can't apply taint in different scenarios based on the class inheritance.  I'm not sure quite how to describe it, other than it doesn't seem to be considering all the possible implementations behind a pointer, and this results in taint not being applied at the correct place.

I've minified this reproducer heavily, but this was encountered while trying to get taint tracking working on Firefox, so it originally came from a real use case, using CTU, across a few object files and a lot of source/header files.  If this is considered 'not a bug' I would welcome recommendations on how we can annotate or restructure things so that the taint tracking can actually work.

In the example below Statements 1A and 2A show the behavior as I would expect/hope it to work.  Statements 1B and 2B show scenarios where it doesn't do the expected thing; these represent how Firefox's code is actually structured; I needed to modify both of those places to get it to behave the way I expected.

```
#include <stdio.h>

void clang_analyzer_isTainted(int);

/*
  Class Hierarchy:

        Actor◄───┐
                 │---Parent
        PParent◄─┘

        Base ◄── Handler

  Control Flow:

    start: PParent::OnMessageReceived
           Parent::RecvCancel
           Handler::OnRecvCancel
*/

// ==========================================

class Base  {
 public:
  virtual void OnRecvCancel(int port) = 0;
};

class Handler final : public Base {
 public:
  void OnRecvCancel(int port) override;
};

// ------------------------------------------

class PParent 
{
public:
    bool OnMessageReceived() ;
};

class Actor {
 public:
  explicit Actor(Base* aRequest) : m(aRequest) {}

 protected:
  Base* m;
};

class Parent : public Actor, public PParent {
 public:
  explicit Parent(Base* aRequest);

  bool RecvCancel(int port);
};

// ==========================================

Parent::Parent(Base* aRequest)
    : Actor(aRequest) {
}

// ------------------------------------------

void Handler::OnRecvCancel(int port) {
  // SECOND CALL to check taint
  clang_analyzer_isTainted(port);
}

bool Parent::RecvCancel(int port) {
  // FIRST CALL to check taint
  clang_analyzer_isTainted(port);

  // Statement 2A: With this statement (and 1A) things behave as we expect.  We report that
  //               port is tainted on both the first and second calls.
  Handler* foo = (Handler*)m;
  
  // Statement 2B: With this statement (and 1A) we only report that port is tainted on the first call
  //auto foo = m;

  foo->OnRecvCancel(port);
  return true;
}

// ------------------------------------------

auto PParent::OnMessageReceived() -> bool
{
    int port;
    scanf("%i", &port);

    // Not needed, but yes it is Tainted.
    //clang_analyzer_isTainted(port);

    // Statement 1A: With this value (and statement 2A) we correctly report that port is tainted on
    //               the first and second calls
    Parent* foo = (Parent*)0x10;
    
    // Statement 1B: With this value (and statement 2A) we report that port is tainted only on the
    //               first call.  Parent inherits from PParent.
    //Parent* foo = static_cast<Parent*>(this);
    
    // Statement 1C: With this value (and statement 2A) we do not report that port is tainted at all
    //               I presume this is do to optimization as we're causing Undefined Behavior
    //Parent* foo = nullptr;

    return foo->RecvCancel(port);
}
```

Command:
```
clang-17 --analyze -Xclang -analyzer-checker=debug.TaintTest,debug.ExprInspection,alpha.security.taint.TaintPropagation PDNSRequestParent.cpp
```

I'm using a version of clang trunk built a few days ago; it should be revision 4c457e81c4ed78e237b408fb480909a956432638




Statements 1A & 2A

```
../PDNSRequestParent.cpp:45:3: warning: YES [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:45:28: warning: tainted [debug.TaintTest]
  clang_analyzer_isTainted(port);
                           ^~~~
../PDNSRequestParent.cpp:50:3: warning: YES [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:50:28: warning: tainted [debug.TaintTest]
  clang_analyzer_isTainted(port);
                           ^~~~
../PDNSRequestParent.cpp:59:21: warning: tainted [debug.TaintTest]
  foo->OnRecvCancel(port);
                    ^~~~
../PDNSRequestParent.cpp:83:28: warning: tainted [debug.TaintTest]
    return foo->RecvCancel(port);
                           ^~~~
6 warnings generated.
```


Statements 1A & 2B

```
../PDNSRequestParent.cpp:45:3: warning: NO [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:50:3: warning: YES [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:50:28: warning: tainted [debug.TaintTest]
  clang_analyzer_isTainted(port);
                           ^~~~
../PDNSRequestParent.cpp:59:21: warning: tainted [debug.TaintTest]
  foo->OnRecvCancel(port);
                    ^~~~
../PDNSRequestParent.cpp:83:28: warning: tainted [debug.TaintTest]
    return foo->RecvCancel(port);
                           ^~~~
5 warnings generated.
```


Statements 1B and 2A

```
../PDNSRequestParent.cpp:45:3: warning: NO [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:50:3: warning: YES [debug.ExprInspection]
  clang_analyzer_isTainted(port);
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../PDNSRequestParent.cpp:50:28: warning: tainted [debug.TaintTest]
  clang_analyzer_isTainted(port);
                           ^~~~
../PDNSRequestParent.cpp:59:21: warning: tainted [debug.TaintTest]
  foo->OnRecvCancel(port);
                    ^~~~
../PDNSRequestParent.cpp:83:28: warning: tainted [debug.TaintTest]
    return foo->RecvCancel(port);
                           ^~~~
5 warnings generated.
```


</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWkuP27jS_TXsTcGGTPm58MJ2d2MamC8Jkgzmu6uAEksWJxSpISm7PYv72y9I0e9Hdx7AzAAtBLab5uPUqVPFIh1mrVgqxCkZzMng_o41rtRm6nRlhHNoVsu7TPPN9InQ0Qqh0I3iwKDANdSS5WhhXaJBcCXCJ8ecyGGmmNxYYeFBLYVCyJkidOSA1bXcgGNCORAKuCgKNKgc2BwVM0JbyJhFDlqF6XLJrAWhSjTCMZVjF8DDqEBpB7YxCH82wiGUeg1OA0ebG5EhCEfoArQr0YArmQLhgGu0LQyLWPnuGUKulRUcjVBLYFKGVWttrcgkgqhqiRUqb5RWFjIsRbC91kI5NH4Npji4UlgwaBvpPNpooIeYYZi4rqVADsy1VmljMHcte12S3JNk1r5GiiuhROEHxIlro3mTo4ES2UrIjV83a1z79ZpZQJXrxiNCDutSSARnNn5lp2GJLgJyhuVffetam_CuFTwKg4V-9jNa7VnSRiyFYlJuIGcVQmF0BQwMMgmN9a606Hs31s-w-PxbICE32tooCp394a0rhEQb6GEgtQNdgNWNyZHQxxIZR9N28S4tWlOE3fkDORA68hQyyJoloSN4grVuJIc1ylxXCAZzXVWoePSOVkEG6yA3YEppxxyCNt41zjS5a4JKhVpab6wroz9O2Amjc9cEDjxVxy5qlYnPzIsDMpR6HWQfhGKhNws20xnYIMrS9ynZSmgDzO6MwOcac-ep0LWXq_dUWAuOJpu3k83byfZR0kbckai5jsD8xK121JKkc99qMagIrY81P9PO7SNPOUdP_c7mHVncD38Chcj9hBoqzUWxgUy70vvTldriNglEqbWmBJPblLBmG3jawTrikgyT-K_9k6ZC5bLhCCRdWMeF7pYkfTgcstKC-7Sgll-YTzJ_ofki7GfvQeSEjoVyhE5IOj9ahz4SGj8DLEJS-UWgYSYvNySdHfaF-Mxypw15oGQyIuN--NAn4-Tqh0lyPH73bDvSTqfzgflsd9zxQ2y8ttRkfAnenFmEG_DgF6a4RHM8dqGVM1rCo9TrC3Zbx4wj6WyHKZ2RdPZe_R9ay5b4EXMUK-Rnhh72_oj5auFTtTzrtoUUZz3t6V1EH8_89ggkvf87_x0AavejwD2QUdQY1E0mRb7jE2AljA8lCGI9MjQIFGptvEq9YZDstTq6P9Ftu1ykDQqflsG7p10wauAGjBeW1ys0RnC8gSB6oPPq5xx-1BJsl4jzn6EFyLSWcK42Om65eoGmELC36MDnWopcuBjadDwPW9kM2Ef8s0EbXTKDitDxUdto7hc9DJbaaBfy2cH82-mqF6FuGdm7MkJabP_ekfYKc2L0XbTnZPnI8TVFvCyEf04oHuacmwzs5OXp3rr-1L07q3-W9kPsXU94J3lg52WIi356WLx_dw-L2a-_-u00LzH_2tYp24439sBL3jyAFiRwJWW_hOvx6eOnzz8L1onJ27IHqAcFvwtXtmWh3X3jPac49GYeXazkYqnBrK_82jKjC_B7qHi0caHMO1nq-Am9hG3taM8eocDxxUshjHWhBrOYa8UhZ1La7na-rYPpDAqtQz4ndLxvJXSyzwYA1y2ev8riNYJWcnNo2SX0e-Ae7fGirHF6h7U680WhdYekDydaPfUcgEHXGAXONHhNZj8UPgHmC1VIuy94uCGrnewv3rM7LacHjTZnqgiDKaEDEd4WQOjwmj53_nqnXayFtwewDVpf8AoLUebd00HfEQ8X9NE7iYgVkw1utWEPA6dVSTxhviiVsyWPn-sRsB-4zb1HEbBrJHSSPPeSIwfcsnP-bXbetk5uYjS8YOY-Vrpbe7Z3DrY9_0Ylnnn33HgbLkC-5Mw6ki72PKQPhI69TcdxdJuNxbexwXW4c7hFCnNwkBKu8PEE_qjYVLg7lfuzpQZdO1GJv8Jxu823hI6MP263lwG_KY6FUMhhHk-8L_OlGilrZy4EQUwxMSPdzEf7zHNyoAyvC11VTO0rtZNOIUI7vRF0OjFMofP_oRG2DaYTdjq_k99zzJplN0Tx51BALNqWh-faPCnrtx-hFaELJuuSdS3mjRFu0w0eaMd9MLpmy5bGD_fvPsVaJGosr-sbxrS3Xy3fDFZorJ9FF-3G6xOy-gpZI6SLtzGcbSywpfZHeeHAluH6IfOxsxJhcD_vD0Y47uV95KMx0nSU9ZNxkfXHySSZsMlg2E_pMD06hp6_Hl-BEDoEOrtx1u92vRwuGp_O-gOSzlIv_jUzKlxjzOA_D5-ADOYX2R7cf0f9AUAGD_-99bwWKh2fYN2G2w7vXi_fCfXq09rwCqSD5F9DaoD67yB14pH2vgfpa0utH0A3Tr-bx2_Kv69kcrhFYWGJCg07uA-8lOuuJpb5T00s797_U0PgLVrfovVvi9bBD0dr_PHi55YBb9H6Fq1v0frD0XrHpymfpBN2h9PecJyOaX806t2V01GfF4OkYIxOhqPxmCbZKKGDXj7sFVmWD9mdmNKEpsmg1-uNkmGv1-VsgL1h2kuTJOF9zkk_wYoJ2ZVyVXW1Wd4JaxucDulwmN5JlqG04f8aUKpwDeFLQikZ3N-ZqR_TyZqlJf1ECuvsfhYnnMTp52u_rbc_QbcX7CWK8OOeQHvXGDktnautPwCGU-hSuLLJurmuCH3008e3Tm30H-2vsgGUJfQxgP5fAAAA__9iCd5z">