drh/lcc — pull request #13 by mycoboco (2014-12-10 06:48:43+00:00)
Title: Fixed to correctly diagnose expressions with NPC

This commit lets lcc correctly diagnose the following code:

```
typedef void (*fp_t)(void);

fp_t func(fp_t param)
{
return (void *)0; /* line A */
}

int main(void)
{
fp_t t = (void *)0; /* line B */
t = (void *)0; /* line C */
return func((void *)0) /* line D */
== (void *)0;
}
```

According to the Standard, the commented lines above should not be considered non-portable while lcc says:

```
5: warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent
10: warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent
11: warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent
12: warning: conversion from `pointer to void' to `pointer to void function(void)' is compiler dependent
```

This brings a side effect that the following code snippet is silently compiled because of constant folding even if conditional expressions are not qualified as constant expressions by the Standard.

```
fp_t func(fp_t param)
{
return (1)? (void *)0: (void *)0; /* should be diagnosed */
}
```

I think this is not a big problem and can be resolved by introducing a new option (or changing the `-A -A` option) to force the strict concept of constant expressions if necessary; adding a `RIGHT` node for each conditional expression folded to a constant would be enough.