Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Analyzer fails to recognize C-style union struct initialization #38856

Open Quuxplusone opened 5 years ago

Quuxplusone commented 5 years ago
Bugzilla Link PR39884
Status NEW
Importance P normal
Reported by Renat Idriso (renat@idrisov.info)
Reported on 2018-12-04 17:28:11 -0800
Last modified on 2019-05-09 23:27:04 -0700
Version 7.0
Hardware PC Linux
CC dcoughlin@apple.com, htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, penryu@gmail.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Hi All,
I run analysis on a piece of code with:

$ clang-tidy tidy-minimal.c -checks=* --

Code:

#include <stdio.h>
#include <stdlib.h>

struct a {
  union {
    struct {
      void *b;
    };
  };
};

void *something();
void something_else(struct a *param);

void myfunction() {
  struct a c = { .b = malloc(256) };
  something_else(&c);
}

int main() {
  myfunction();
}

----------------
I get:
/.../tidy-minimal.c:18:1: warning: Potential memory leak [clang-analyzer-
unix.Malloc]
}
^
/.../tidy-minimal.c:21:3: note: Calling 'myfunction'
  myfunction();
  ^
/.../tidy-minimal.c:16:23: note: Memory is allocated
  struct a c = { .b = malloc(256) };
                      ^
/.../tidy-minimal.c:18:1: note: Potential memory leak
}
^
----------------

It looks like it is not handling struct initialization properly because if I
remove union -- it produces no warnings

The issue could be related to https://bugs.llvm.org/show_bug.cgi?id=35882
but in my case giving union a name does not resolve it.

Thanks!
Quuxplusone commented 5 years ago
I tried it on 7.0svn but does not seemed to reproduce?

root@877aa7b58ab3:~/test# clang-tidy tidy-minimal.c -checks=*
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "tidy-minimal.c"
No compilation database found in /root/test or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or
directory
json-compilation-database: Error while opening JSON database: No such file or
directory
Running without flags.
18 warnings generated.
/root/test/tidy-minimal.c:20:1: warning: Potential memory leak [clang-analyzer-
unix.Malloc]
}
^
/root/test/tidy-minimal.c:23:3: note: Calling 'myfunction'
  myfunction();
  ^
/root/test/tidy-minimal.c:18:23: note: Memory is allocated
  struct a c = { .b = malloc(256) };
                      ^
/root/test/tidy-minimal.c:20:1: note: Potential memory leak
}
^
Suppressed 17 warnings (17 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -
system-headers to display errors from system headers as well.
Quuxplusone commented 5 years ago
Hi Peter,
I am not sure I understand you comment,
from the output you provided it looks like it is reproduced, but you say it is
not,
I am confused,
if your output is the same why is it not reproduced?
Quuxplusone commented 5 years ago

According to your statement "It looks like it is not handling struct initialization properly because if I remove union -- it produces no warnings", but I have removed the union "--" (as shown in command line) and it still show warnings - exactly the opposite of what you have said. Sorry, is that correct, or did I did something wrong?

Thanks.

Quuxplusone commented 5 years ago

My misunderstanding comes from what is "removing the union and produces no warning" means?

Quuxplusone commented 5 years ago
Oh, I see we understand "removing the union" differently, what I mean is the
following code:

#include <stdio.h>
#include <stdlib.h>

struct a {
    void *b;
};

void *something();
void something_else(struct a *param);

void myfunction() {
  struct a c = { .b = malloc(256) };
  something_else(&c);
}

int main() {
  myfunction();
}

all the same, but no union,
this code does not produce any warning:

$ clang-tidy tidy-minimal-no-union.c -checks=* --
445 warnings generated.
Suppressed 445 warnings (445 in non-user code).
Use -header-filter=.* to display errors from all non-system headers. Use -
system-headers to display errors from system headers as well.
$
Quuxplusone commented 5 years ago
I'm able to reproduce this on a further minimalized source file that might
better illustrate issue:

##### BEGIN #####

renat>% clang-tidy --version
LLVM (http://llvm.org/):
  LLVM version 7.0.1
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: broadwell
renat>% clang-tidy -version
LLVM (http://llvm.org/):
  LLVM version 7.0.1
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: broadwell
renat>% cat tidy-minimaler.c
#include <stdlib.h>

struct a {
#ifdef WITH_UNION
    union {
#endif /* WITH_UNION */
            void *b;
#ifdef WITH_UNION
    };
#endif /* WITH_UNION */
};

void something_else(struct a *param);

void myfunction() {
    struct a c = { .b = malloc(256) };
    something_else(&c);
}
renat>% clang-tidy tidy-minimaler.c --
renat>% clang-tidy tidy-minimaler.c -- -DWITH_UNION
1 warning generated.
/home/penryu/code/Eden/renat/tidy-minimaler.c:18:1: warning: Potential memory
leak [clang-analyzer-unix.Malloc]
}
^
/home/penryu/code/Eden/renat/tidy-minimaler.c:16:25: note: Memory is allocated
    struct a c = { .b = malloc(256) };
                        ^
/home/penryu/code/Eden/renat/tidy-minimaler.c:18:1: note: Potential memory leak
}
^

##### END #####

The analyzer is warning of a memory leak when the struct contains a union, but
not when the union is absent. The union should have no relevance to the leak.