Bug #3378
closedFields having array type without specified size are processed incorrectly
0%
Description
For example, there is such the structure in module drivers/net/wireless/rtlwifi/rtlwifi.ko:
struct ieee80211_regdomain { u32 n_reg_rules; char alpha2[2]; u8 dfs_region; struct ieee80211_reg_rule reg_rules[]; };
after C backend it becomes:
struct ieee80211_regdomain { u32 n_reg_rules; char alpha2[2U]; u8 dfs_region; struct ieee80211_reg_rule reg_rules[0U]; };
that leads to compilation (and BLAST) errors during initialization.
Updated by Alexey Khoroshilov about 12 years ago
A simple solution is to add a check for zero as an array size in C backend and to omit its printing.
The only drawback is incorrect processing of zero-length arrays.
But zero-length array is a gcc-specific extension, while flexible array member is a part of C99 standard.
Updated by Evgeny Novikov about 12 years ago
- Priority changed from Normal to High
I hope that I will be able to find out difference between '[]' and '[0]' in GCC internals and print correct code always.
Updated by Evgeny Novikov about 12 years ago
In fact the issue described didn't lead to errors. It looks like there is a bug in CIL or/and BLAST. Here is the simplest example to reproduce the issue (test2_short.c):
struct S
{
int field;
int arr[];
};
struct S var1 = { .field = 0, .arr = { [0] = 1 } };
struct S var2 = { .field = 0, .arr = { [0] = 1, [1] = 2 } };
int main() { return 0; }
int func() { ERROR: goto ERROR; }
When I run blast:
pblast.opt test2_short.c test3.c
(where test3.c is empty file) I have following errors:
error in createGlobal(var2: test2_short.c:7): Errormsg.ErrorPutting in initializer __BLAST_initialize_test2_short.c No reroute info supplied! Error: There were parsing errors in test3.c Timings: TOTAL 0.001 s (1) Parse: 0.001 s (1) Ack! The gremlins again!: Errormsg.Error Ack! The gremlins again!: Errormsg.Error Fatal error: exception Errormsg.Error
It's interesting if I exclude test3.c from launch BLAST produces safe.
The C code above (test2_short.c) is correct.
If I remove designator's constants
struct S var2 = { .field = 0, .arr = { 1, 2 } };
then BLAST produces safe, but for such the cases:
struct S var2 = { .field = 0, .arr = { 1, [3] = 2 } };
I cannot remove designator's constants and BLAST fails anyway.
Updated by Alexey Khoroshilov about 12 years ago
And why blast worked well without aspectator? What is the difference?
Updated by Evgeny Novikov about 12 years ago
Alexey Khoroshilov wrote:
BLAST works well without aspectator because of original preprocessed source code doesn't contain explicit designator's constants in initialization:And why blast worked well without aspectator? What is the difference?
static const struct ieee80211_regdomain rtl_regdom_11 = {
.n_reg_rules = 1,
.alpha2 = "99",
.reg_rules = {
{ .freq_range.start_freq_khz = ((2412-10) * 1000), .freq_range.end_freq_khz = ((2462+10) * 1000), .freq_range.max_bandwidth_khz = ((40) * 1000), .power_rule.max_antenna_gain = ((0) * 100), .power_rule.max_eirp = ((20) * 100), .flags = 0, },
}
};
static const struct ieee80211_regdomain rtl_regdom_12_13 = {
.n_reg_rules = 2,
.alpha2 = "99",
.reg_rules = {
{ .freq_range.start_freq_khz = ((2412-10) * 1000), .freq_range.end_freq_khz = ((2462+10) * 1000), .freq_range.max_bandwidth_khz = ((40) * 1000), .power_rule.max_antenna_gain = ((0) * 100), .power_rule.max_eirp = ((20) * 100), .flags = 0, },
{ .freq_range.start_freq_khz = ((2467-10) * 1000), .freq_range.end_freq_khz = ((2472+10) * 1000), .freq_range.max_bandwidth_khz = ((40) * 1000), .power_rule.max_antenna_gain = ((0) * 100), .power_rule.max_eirp = ((20) * 100), .flags = NL80211_RRF_PASSIVE_SCAN, },
}
};
But if there will be explicit designator's constants in original code then BLAST will fail.
Temporarily workaround at the level of CIF is to omit designator's constants if they are (0, 1, 2, ...). But I consider such the workaround to be very bad, since it's hard to implement (CIF isn't intended for such things) and it doesn't solve the problem in general.
I guess 2 things should be done:
- We should investigate why BLAST doesn't fail when it has one file with parsing errors (most likely with other kinds of errors too) as input and fails when it has several files at least one of which has parsing errors.
- We should fix CIL or report CIL developers since CIL doesn't parse correct programs. For us this means that it can build incorrect program model that will lead to tricky failures (e.g. with using advanced pointer analysis).
Updated by Evgeny Novikov about 12 years ago
Evgeny Novikov wrote:
(where test3.c is empty file) I have following errors:
[...]
I forgot to copy from BLAST output such the error message:
test2_short.c:7: Error: INDEX designator is outside bounds
It looks like CIL remembers for flexible arrays the number of array elements after the first initialization and then when more elements are initialized it fails.
Updated by Evgeny Novikov about 12 years ago
- Published in build set to 760fa8a
Fix of the original bug I have merged to master in commit 760fa8a. Wait for test results.
Updated by Evgeny Novikov about 12 years ago
- Status changed from Open to Closed