>>! In D2498#10, @jyoti.yalamanchili wrote:
> Hi David,
> 
>>>! In D2498#9, @dblaikie wrote:
>>>>! In D2498#4, @jyoti.yalamanchili wrote:
>>> This bug appears only when typedef is used.
>> 
>> Doesn't look like it.
> This was my previous analysis which was incorrect. This issue occurs whenever 
> explicit casting occurs. The type to which we are explicitly casting is not 
> emitted in debug info.
>> 
>> Changing the code to cast to (S*) instead of (T) still demonstrates the bug 
>> and is still present even with this patch applied.
>> 
> As you mentioned, I verified this for the following code snippet where i am 
> replacing T with struct S* and the result was that DW_TAG_structure_type & 
> DW_TAG_member were emitted but not DW_TAG_typedef because T was not used. I 
> thought this is expected behaviour. Please correct me if i am wrong.

Looks like I was confused (perhaps by the old title of this code review which 
still mentions typedefs - and perhaps by Phab showing me the newer diff, or 
maybe I was looking in the wrong place somehow and saw the old code which still 
special-cased for typedefs). Now that I apply your latest patch properly I see 
the behavior you describe - this fixes the issue regardless of whether a 
typedef is used.

> 
> typedef struct S {
>   int i;
> } *T;
> #define M(p) (**(struct S*)**(p))
> 
> void foo(void *p) { M(p)->i++; }
> 
> 
>> The problem is more general than typedefs and casts - arguably we should get 
>> this (C++11) case too:
>> 
>>   struct S { int i; };
>>   void func(S);
>>   void func() {
>>     func(S{42});
>>   }
>> 
>> but GCC doesn't get this either, so I'm less concerned.
>> 
>> GCC does get the cast case - with or without a typedef. So perhaps we can 
>> just deal with casts for now... 
>> 
> Okay. 
> 
>> The only other thing I can think of is far more invasive/more work - to get 
>> this all right, what we really need is a tree of "completeness" - keeping 
>> track of any time a type is required to be complete (not just a single bit 
>> that says "this has been required to be complete") & then emitting any type 
>> for which it was requried to be complete during a function we codegen'd.
>> 
> Sorry, could you please explain this with an example ?

  struct foo { };
  inline void func() { foo f; } // this makes 'f' required to be complete, 
which means we emit a definition of 'f' if we ever need any reference to 'f'
  foo *f; // this causes us to emit 'f'

Without the second line, we just emit a declaration (in the default 
-fno-standalone-debug mode). 

> I could mention this in the testcase as a TODO note if you want so we don't 
> loose track of this improvement scope.

That's OK - it's pretty much outside the scope of your change. It wouldn't 
really belong in this test file.

> 
>> This infrastructure would also allow us to do a better job minimizing debug 
>> info for the limited debug info optimization where we currently fail:
>> 
>>   struct foo { ... };
>>   inline void unused() { foo f; } // 'f' is required to be complete here, 
>> but the function is never called
>>   foo *f; // but that required completeness is never relied upon for this TU 
>> - a declaration would've sufficed
>> 
>> This hurts us in, for example, Clang's own Sema.h - the giant Sema class has 
>> a single non-member inline function right after it that has dereferences a 
>> Sema pointer, thus requiring Sema to be complete. From then on, if anything 
>> else in the TU including Sema.h requires Sema (evern just a pointer to it 
>> it) the debug info for the entire class will be emitted.
> 
> If i understand this correctly, point of worry here is about the increase in 
> debug info size, am i right? 

The -fno-standalone-debug default option is an attempt to minimize debug info 
size, yes. The issue is that it uses /some/ part of the powers necessary to 
make our general debug info strategy more reliable and to fix this bug you're 
addressing and possible others in a more general manner. Though I can't site 
any particular examples similar to yours (places where a type is used, but no 
named instance or reference to the type is ever needed)... actually I can:

 struct S { };
 void *v = new S;

Clang doesn't emit debug info describing 'S' (but then again, neither does 
GCC). I imagine maybe there's a few other pieces of syntax that allow one to 
reference a type without ever naming a variable of that type.

> But, we certainly need the debug info of any referenced variables isn't ?

Sure - in this case there was no variable, but it's still reasonable to 
describe the type. The rough heuristic is: Any expression written in executing 
code (global intializers, functions that are actually codegen'd, etc) should be 
able to be written and executed in a sufficiently advanced debugger given the 
information Clang produces. 

Any cases where the information is fundamentally not there - are bugs.

================
Comment at: llvm/tools/clang/lib/CodeGen/CGExprScalar.cpp:279
@@ +278,3 @@
+    CGDebugInfo *DI = CGF.getDebugInfo();
+    if (DI &&
+        CGF.CGM.getCodeGenOpts().getDebugInfo() >=
----------------
Roll the DI variable into the if condition and sink the LimitedDebugInfo check 
into the DI function (at least I think that's how we are/should be doing this - 
keeping as much of the implementation details down in CGDebugInfo rather than 
up in the CodeGen callsites)

================
Comment at: llvm/tools/clang/test/CodeGen/Debug-info-explicitcast.c:4
@@ +3,3 @@
+typedef struct S { int i; } *T;
+#define M(p) ((T)(p))
+
----------------
Could you drop the macro usage and the typedef as they're not needed to 
demonstrate the fundamental bug here?

http://reviews.llvm.org/D2498



_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to