First Last Prev Next    No search results available
Details
: [llvm-gcc] "Address of label" GCC extension not implemented
Bug#: 273
: tools
: llvm-gcc
Status: RESOLVED
Resolution: FIXED
: All
: All
: 1.0
: P2
: minor
: 1.2

:
: missing-feature
: 296
:
  Show dependency tree - Show dependency graph
People
Reporter: Chris Lattner <sabre@nondot.org>
Assigned To: Chris Lattner <sabre@nondot.org>

Attachments


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2004-03-08 19:09
This is just a tracking bug that points out that we don't currently support the
'address of a label' GCC extension.  This extension is often used to make
'threaded' interpreters.   It would be good to support this eventually.

Here's a simple example:

---
int code[]={0,0,0,0,1};
void foo(int x) {
  volatile int b;
  b = 0xffffffff;
}
void bar(int *pc) {
  static const void *l[] = {&&lab0, &&end};

  foo(0);
  goto *l[*pc];
 lab0:
  foo(0);
  pc++;
  goto *l[*pc];
 end:
  return;
}
int main() {
  bar(code);
  return 0;
}
---

-Chris
------- Comment #1 From Brian R. Gaeke 2004-03-12 15:47:36 -------
Do you think we should have labels as values, like in gcc, then? Or should we
do some kind of l33t 
transformation that lowers the uses of labels as values to switch or branch
statements or something?
------- Comment #2 From Chris Lattner 2004-03-12 16:28:13 -------
Yes, we will have a leet transformation.  I don't intend to extend LLVM to
support this.  :)

-Chris
------- Comment #3 From Chris Lattner 2004-03-16 00:11:01 -------
This is ugly.  Apparently GCC allows one to do stuff like this as well.  Cute!
:)

  static const int array[] = { &&foo - &&foo, &&bar - &&foo,                   

                             &&hack - &&foo };
  goto *(&&foo + array[i]);

I'm looking into adding support for this now.

-Chris
------- Comment #4 From Chris Lattner 2004-03-16 02:28:15 -------
As it turns out, GCC doesn't implement exceptions or destructors correctly in
the presence of indirect gotos either.  Here's a testcase.  When we implement it
correctly and GCC doesn't, I will file a GCC bug report.

-Chris

---
#include <stdio.h>

namespace {
  struct S {
    int V;
    S(int v) : V(v) {
      printf("create %d\n", V);
    }
    ~S() {
      printf("destroy %d\n", V);
    }
  };
}

int main() {
  static const void *L[] = {&&L1, &&L2, &&L3, &&L4, 0 };
  unsigned i = 0;
  S a(0);  
L1:
  S b(1);
L2:
  S c(2);
L3:
  S d(3);
  goto *L[++i];
L4: return 0;
}
---
------- Comment #5 From Chris Lattner 2004-03-16 02:53:29 -------
This is now implemented.  Primary patch here:
http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040315/013179.html

Testcases here:
test/Regression/CFrontend/2004-03-15-SimpleIndirectGoto.c
test/Programs/SingleSource/Regression/C/2004-03-15-IndirectGoto.c 

Note that this does not work correctly in the presence of exceptions and C++
cleanups, but then again, neither does the native GCC compiler.

This GCC extension is widely used to implement "threaded interpreters", so
supporting it is useful. :)

-Chris

First Last Prev Next    No search results available