[cfe-dev] Uninitialized Variables Analysis crashing

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Wed Sep 26 12:11:51 PDT 2018


Hmm, do we have a backtrace from a debug+assertions build? Like, what 
are we specifically crashing at? It kinda makes sense that we should 
have the variable in the vals list, because we went through its 
respective DeclStmt, right? So i dunno where we are crashing.

I also dumped the AST for the pseudo-code that you provided and i 
noticed more inconsistencies with your AST:

- Integral cast from int to unsigned is missing within operator ==.
- The lvalue-to-rvalue around operator & in the __spec_begin call is 
unnecessary because operator & already returns an rvalue.
- On the other hand, DeclRefExprs for both __setjmp_buf and __setjmp_ret 
must be lvalues.

It's also a bit weird that there's no control flow in your CFG. I would 
have expected that a new block is going to start after operator ==, but 
i guess if the user code is unmodified anyway, there probably isn't much 
control flow anyway. But then what's the point of comparing? I'm confused.

 > One thing I have noticed from the CFG is that all my calls were 
tagged "template".

CFG just calls Stmt::printPretty() in this case. A quick look at Stmt 
pretty-printing suggests that you have created the DeclRefExpr for the 
function with a non-empty template keyword source location, i.e. this 
AST pretends to be constructed from code

     unsigned int __spec_mode = template __spec_begin(...);

Also your variables have type 'auto'. And, as far as i understand, we're 
dealing with C code.

So just to be sure - are you sure you want to auto-generate AST? Did you 
consider implementing your feature as a macro instead, probably with the 
help of a custom compiler builtin for __spec_begin() if it does 
something that a normal function cannot do? I.e., implement all special 
features in the builtin, and instead of auto-generating the surrounding 
AST, just add a macro into the header that expands to whatever you want? 
It's not as omnipotent, but it's much easier. Like, i mean, this AST 
compiles, but all clang tools are screwed unless the AST makes perfect 
sense; this compiler warning is just the first slightly-advanced tool 
you encountered.

On 9/25/18 3:27 PM, João Paulo Labegalini de Carvalho wrote:
> Yes, I understand and really appreciate your help, Artem.
>
> Last night I had the same insight, but splitting the VerDecls to 
> different DeclStmts had no effect.
>
> Bellow is the dump of the source-level CFG for the block in question. 
> One thing I have noticed from the CFG is that all my calls were tagged 
> "template". Any idea why?
> Maybe that has something to do with why UninitializedVariables 
> Analysis is sigseg-faulting.
>
> [B181]
>    1: jmp_buf __setjmp_buf;
>    2: *template* setjmp
>    3: [B181.2] (ImplicitCastExpr, FunctionToPointerDecay, int 
> (*)(struct __jmp_buf_tag *))
>    4: __setjmp_buf
>    5: [B181.4] (ImplicitCastExpr, ArrayToPointerDecay, struct 
> __jmp_buf_tag *)
>    6: [B181.3]([B181.5])
>    7: int __setjmp_ret = *template* setjmp(__setjmp_buf);
>    8: *template* __spec_begin
>    9: [B181.8] (ImplicitCastExpr, FunctionToPointerDecay, unsigned int 
> (*)(jmp_buf *, int))
>   10: __setjmp_buf
>   11: &[B181.10]
>   12: __setjmp_ret
>   13: [B181.12] (ImplicitCastExpr, LValueToRValue, int)
>   14: [B181.9]([B181.11], [B181.13])
>   15: unsigned int __spec_mode = *template* 
> __spec_begin(&__setjmp_buf, __setjmp_ret);
>   16: __spec_mode
>   17: [B181.16] (ImplicitCastExpr, LValueToRValue, unsigned int)
>   18: [B181.17] == 1
>   19: *template* __begin_spec_slow_path
>   20: [B181.19] (ImplicitCastExpr, FunctionToPointerDecay, void (*)(void))
>   21: [B181.20]()
>   22: global_maxNumVertices
>   23: [B181.22] (ImplicitCastExpr, LValueToRValue, ULONGINT_T)
>   24: (long)[B181.23] (CStyleCastExpr, IntegralCast, long)
>   25: long __tmp_maxNumVertices = (long)global_maxNumVertices;
>   26: __tmp_maxNumVertices
>   27: typeof (tmp_maxNumVertices) ___a = (__tmp_maxNumVertices);
>   28: maxNumVertices
>   29: [B181.28] (ImplicitCastExpr, LValueToRValue, ULONGINT_T)
>   30: 1 (ImplicitCastExpr, IntegralCast, unsigned long)
>   31: [B181.29] + [B181.30]
>   32: typeof (maxNumVertices + 1) ___b = (maxNumVertices + 1);
>   33: ___a
>   34: [B181.33] (ImplicitCastExpr, LValueToRValue, typeof 
> (tmp_maxNumVertices))
>   35: [B181.34] (ImplicitCastExpr, IntegralCast, unsigned long)
>   36: ___b
>   37: [B181.36] (ImplicitCastExpr, LValueToRValue, typeof 
> (maxNumVertices + 1))
>   38: [B181.35] > [B181.37]
>    T: ([B181.38]) ? ... : ...
>    Preds (1): B185
>    Succs (2): B179 B180
>
>
>
> On Tue, Sep 25, 2018 at 2:47 PM Artem Dergachev <noqnoqneo at gmail.com 
> <mailto:noqnoqneo at gmail.com>> wrote:
>
>     Remote debugging is hard, but here's something i notice: i don't
>     think you can declare multiple variables of different types in the
>     same DeclStmt. Eg., you can do `int x = 1, *y = 0;`, but you can't
>     do `int x = 1, unsigned y = 0;`. Could you try to produce a
>     separate DeclStmt for every VarDecl and see if it helps?
>
>     If it doesn't, can i also have a look at the CFG? Just do CFG.dump().
>
>     On 9/24/18 3:26 PM, João Paulo Labegalini de Carvalho wrote:
>>     Artem,
>>
>>     First of all, thank you for your reply.
>>
>>     Indeed, I am auto-generating AST made of regular nodes. More
>>     specifically, my SpecStmt node has four sub-nodes. A DeclStmt
>>     that I use to hang the variables a need, a Expr to compare
>>     __spec_mode and decide which path to take (SlowPath or FastPath)
>>     and two CompoundStmts. So SpecStmt looks like an IfStmt with both
>>     then and else statements.
>>
>>     Bellow is the part of the AST which triggers the sigsegv (Please
>>     find the AST for the whole FunctionDecl attached):
>>
>>     |   |       |-*SpecStmt* 0x15c1ca8 <./spec.h:127:32>
>>     |   |       | |-DeclStmt 0x15c09e8 <col:32>
>>     |   |       | | |-VarDecl 0x15c0368 <col:32> col:32
>>     *__setjmp_buf* 'jmp_buf':'struct __jmp_buf_tag [1]' auto
>>     |   |       | | |-VarDecl 0x15c03c8 <col:32> col:32
>>     *__setjmp_ret* 'int' auto cinit
>>     |   |       | | | `-CallExpr 0x15c0630 <col:32> 'int'
>>     |   |       | | |   |-ImplicitCastExpr 0x15c0618 <col:32> 'int
>>     (*)(jmp_buf *)' <FunctionToPointerDecay>
>>     |   |       | | |   | `-DeclRefExpr 0x15c05e0 <col:32> 'int
>>     (jmp_buf *)' Function 0x15c04d8 '*setjmp*' 'int (jmp_buf *)'
>>     |   |       | | |   `-ImplicitCastExpr 0x15c0450 <col:32>
>>     'jmp_buf *' <ArrayToPointerDecay>
>>     |   |       | | |     `-DeclRefExpr 0x15c0428 <col:32>
>>     'jmp_buf':'struct __jmp_buf_tag [1]' Var 0x15c0368
>>     '*__setjmp_buf*' 'jmp_buf':'struct __jmp_buf_tag [1]'
>>     |   |       | | `-VarDecl 0x15c0660 <col:32> col:32
>>     *__spec_mode* 'unsigned int' auto cinit
>>     |   |       | |   `-CallExpr 0x15c0990 <col:32> 'unsigned int'
>>     |   |       | |     |-ImplicitCastExpr 0x15c0978 <col:32>
>>     'unsigned int (*)(jmp_buf *, int)' <FunctionToPointerDecay>
>>     |   |       | |     | `-DeclRefExpr 0x15c0940 <col:32> 'unsigned
>>     int (jmp_buf *, int)' Function 0x15c07d0 '*__spec_begin*'
>>     'unsigned int (jmp_buf *, int)'
>>     |   |       | |     |-ImplicitCastExpr 0x15c0730 <col:32>
>>     'jmp_buf *' <LValueToRValue>
>>     |   |       | |     | `-UnaryOperator 0x15c06e8 <col:32> 'jmp_buf
>>     *' prefix '&'
>>     |   |       | |     |   `-DeclRefExpr 0x15c06c0 <col:32>
>>     'jmp_buf':'struct __jmp_buf_tag [1]' Var 0x15c0368
>>     '*__setjmp_buf'* 'jmp_buf':'struct __jmp_buf_tag [1]'
>>     |   |       | |     `-ImplicitCastExpr 0x15c0748 <col:32> 'int'
>>     <LValueToRValue>
>>     |   |       | |       `-DeclRefExpr 0x15c0708 <col:32> 'int' Var
>>     0x15c03c8 '*__setjmp_ret*' 'int'
>>     |   |       | |-BinaryOperator 0x15c0a60 <col:32> 'bool' lvalue '=='
>>     |   |       | | |-ImplicitCastExpr 0x15c0a28 <col:32> 'unsigned
>>     int' <LValueToRValue>
>>     |   |       | | | `-DeclRefExpr 0x15c0a00 <col:32> 'unsigned int'
>>     lvalue Var 0x15c0660 '*__spec_mode'* 'unsigned int'
>>     |   |       | | `-IntegerLiteral 0x15c0a40 <col:32> 'int' 1
>>     |   |       | |-CompoundStmt 0x15c1c38 <col:32>
>>
>>
>>     Thanks in advance for any help!
>>
>>     Respectfully,
>>
>>     On Mon, Sep 24, 2018 at 4:36 PM Artem Dergachev
>>     <noqnoqneo at gmail.com <mailto:noqnoqneo at gmail.com>> wrote:
>>
>>         Is the DeclRefExpr for __spec_mode pointing to a valid
>>         VarDecl? Would this VarDecl be encountered previously during
>>         analysis in order to populate TransferFunctions::vals()?
>>         Dunno if that makes sense, i didn't really look at this analysis.
>>
>>         I guess i want to look at your full -ast-dump. It seems that
>>         you are not only adding a new Stmt kind, but also you're
>>         getting into business of auto-generating AST made of some
>>         regular nodes, probably as its children. This is often hard
>>         because it's very easy to break invariants that the normal
>>         AST obeys and there's no way to verify those invariants other
>>         than seeing how everything crashes and debugging.
>>
>>         On 9/24/18 4:43 AM, João Paulo Labegalini de Carvalho via
>>         cfe-dev wrote:
>>>         You are right, I should have been more specific. In my case
>>>         crashing means segmentation fault inside runOnBlock function
>>>         (lib/Analysis/UninitializedValues.cpp).
>>>
>>>         Please find the stack trace attached.
>>>
>>>         On Mon, Sep 24, 2018 at 4:09 AM Csaba Raduly
>>>         <rcsaba at gmail.com <mailto:rcsaba at gmail.com>> wrote:
>>>
>>>             Hi João Paulo,
>>>
>>>
>>>             On Sun, Sep 23, 2018 at 11:39 PM, João Paulo Labegalini
>>>             de Carvalho
>>>             via cfe-dev <cfe-dev at lists.llvm.org
>>>             <mailto:cfe-dev at lists.llvm.org>> wrote:
>>>             > Hi,
>>>             >
>>>             > I have implemented a new Stmt in clang which given
>>>             >
>>>             > __speculate {
>>>             >  // user code
>>>             > }
>>>             >
>>>             > generates LLVM IR equivalent to as if the following
>>>             code was given:
>>>             >
>>>             ...
>>>             >
>>>             > However, if UninitializedVariablesAnalysis is enabled,
>>>             clang crashes at
>>>             > runOnBlock function
>>>             (lib/Analysis/UninitializedValues.cpp). If I disable it
>>>             > via -Wno-uninitialized, the code generated runs
>>>             flawlessly and works as
>>>             > expected.
>>>
>>>             "crash" is a meaningless term. Does it generate an
>>>             access violation,
>>>             an assertion failure, or something else?
>>>             What was the error message? Is there a stack trace?
>>>
>>>
>>>             Csaba
>>>
>>>             -- 
>>>             You can get very substantial performance improvements
>>>             by not doing the right thing. - Scott Meyers, An
>>>             Effective C++11/14 Sampler
>>>             So if you're looking for a completely portable, 100%
>>>             standards-conformat way
>>>             to get the wrong information: this is what you want. -
>>>             Scott Meyers (C++TDaWYK)
>>>
>>>
>>>
>>>         -- 
>>>         João Paulo L. de Carvalho
>>>         Computer Science |  IC-UNICAMP | Campinas , SP - Brazil
>>>         jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
>>>         joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>
>>>         j160924 at dac.unicamp.br <mailto:j160924 at dac.unicamp.br>
>>>
>>>         _______________________________________________
>>>         cfe-dev mailing list
>>>         cfe-dev at lists.llvm.org  <mailto:cfe-dev at lists.llvm.org>
>>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>
>>
>>
>>     -- 
>>     João Paulo L. de Carvalho
>>     Computer Science |  IC-UNICAMP | Campinas , SP - Brazil
>>     jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
>>     joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>
>>     j160924 at dac.unicamp.br <mailto:j160924 at dac.unicamp.br>
>
>
>
> -- 
> João Paulo L. de Carvalho
> Computer Science |  IC-UNICAMP | Campinas , SP - Brazil
> jaopaulolc at gmail.com <mailto:jaopaulolc at gmail.com>
> joao.carvalho at ic.unicamp.br <mailto:joao.carvalho at ic.unicamp.br>
> j160924 at dac.unicamp.br <mailto:j160924 at dac.unicamp.br>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20180926/0c2a43b5/attachment.html>


More information about the cfe-dev mailing list