[cfe-dev] [cfe-commits][patch] Strange LLVM IR result on recursive type

Jin Gu Kang jaykang10 at imrc.kist.re.kr
Wed Nov 7 00:56:31 PST 2012

Hi all,

I found a strange result on clang-3.1 when recursive type was converted. A example is as following.
C language source code:
struct foo1 {
  struct foo2* a;
  struct foo3* b;
struct foo2 {
  void (*func1)(struct foo1*);
struct foo3 {
  void (*func1)(struct foo1*);
struct foo2 e;

Converted result to llvm IR:
%struct.foo2 = type { void (%struct.foo1*)* }
%struct.foo1 = type { %struct.foo2*, %struct.foo3* }
%struct.foo3 = type { {}* }
@e = common global %struct.foo2 zeroinitializer, align 4

struct.foo3 type has "{}*". The reason of strange result is that clang generates struct type for function type with parameter of cycled type as following. 
File: clang/lib/CodeGen/CodeGenTypes.cpp
463     // While we're converting the argument types for a function, we don't want
464     // to recursively convert any pointed-to structs.  Converting directly-used
465     // structs is ok though.
466     if (!RecordsBeingLaidOut.insert(Ty)) {
467       ResultType = llvm::StructType::get(getLLVMContext());
469       SkippedLayout = true;
470       break;
471     }

I think that cycle of types should be cut to translate cycled clang types into llvm IR so clang generates struct type as type holder. Is it right? What do you think about this?

I made a simple patch for clang-3.1 to fix this problem. Resolved result is as following.
Resolved result:
%struct.foo2 = type { void (%struct.foo1*)* }
%struct.foo1 = type { %struct.foo2*, %struct.foo3* }
%struct.foo3 = type { void (%struct.foo1*)* }
@e = common global %struct.foo2 zeroinitializer, align 4

Please review this patch.

Jin-Gu Kang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: RecursiveType.patch
Type: application/octet-stream
Size: 2889 bytes
Desc: RecursiveType.patch
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20121107/2d0cee5e/attachment.obj>

More information about the cfe-dev mailing list