Patch to correctly determine when the address of a compound expression is constant

From http://llvm.org/bugs/show_bug.cgi?id=1891; patch at

http://llvm.org/bugs/attachment.cgi?id=1318, and also attached (I
don't know if GMail will mangle it...).

Patch fixes testcases like:
static int *p = (int ){2, 4};

and

typedef struct Test {int a;int b;} Test;
static Test* ll = &(Test) {0,0};

so that they get through sema correctly.

This patch fixes a few underlying issues:

1. It was previously not possible to determine (AFAIK) whether a
CompoundLiteralExpr was file scope or not, so this patch propagates
that information from the parser. This is the biggest change, but is
mostly mechanical.
2. It makes Expr::hasStaticStorage use that information when necessary.
3. It makes Expr::isConstantExpr deal with arrays that aren't
declarations (currently, that's just compound literals).
4. It changes the order of the checks in Sema::CheckSingleInitializer
so that any necessary implicit casts get added before checking for
whether an initializer is constant.

Expr::isConstantExpr definitely needs more work; it is currently
letting through some expressions that aren't constant, like:
static int r[2] = {1,2};
static int ss[2] = {3,4};
static int t = r-ss; // Wrong: Illegal per C99, and impossible to emit to LLVM
static int* zz = &r[t]; // Wrong: Obviously not constant

Expr::hasStaticStorage and Expr::isConstantExpr probably need to be
restructured to deal with cases like &r[t];

-Eli Friedman

arrayconversionfix.txt (2.91 KB)

Patch fixes testcases like:
static int *p = (int ){2, 4};

and

typedef struct Test {int a;int b;} Test;
static Test* ll = &(Test) {0,0};

so that they get through sema correctly.

This patch fixes a few underlying issues:

1. It was previously not possible to determine (AFAIK) whether a
CompoundLiteralExpr was file scope or not, so this patch propagates
that information from the parser. This is the biggest change, but is
mostly mechanical.
2. It makes Expr::hasStaticStorage use that information when necessary.
3. It makes Expr::isConstantExpr deal with arrays that aren't
declarations (currently, that's just compound literals).
4. It changes the order of the checks in Sema::CheckSingleInitializer
so that any necessary implicit casts get added before checking for
whether an initializer is constant.

Here's a current version of this patch; there were some recent changes
that caused merge conflicts.

-Eli

arrayconversionfixfull.txt (10.6 KB)

Eli,

Thanks for your patch...nice work. Comments below...

Patch fixes testcases like:
static int *p = (int ){2, 4};

and

typedef struct Test {int a;int b;} Test;
static Test* ll = &(Test) {0,0};

so that they get through sema correctly.

This patch fixes a few underlying issues:

1. It was previously not possible to determine (AFAIK) whether a
CompoundLiteralExpr was file scope or not, so this patch propagates
that information from the parser. This is the biggest change, but is
mostly mechanical.

I'd prefer we avoid changing the API or AST.

I just submitted a small patch (r45782) that allows sema to detect when constant expressions are required.

For now, I'd recommend a smaller, focused patch to deal with the following (which my commit doesn't address)...

typedef struct Test {int a;int b;} Test;
static Test* ll = &(Test) {0,0};

Can you resubmit a patch that builds on r45782?

Thanks,

snaroff