Project

General

Profile

Actions

Bug #3378

closed

Fields having array type without specified size are processed incorrectly

Added by Evgeny Novikov almost 12 years ago. Updated almost 12 years ago.

Status:
Closed
Priority:
High
Category:
-
Start date:
08/30/2012
Due date:
% Done:

0%

Estimated time:
Detected in build:
svn
Platform:
Published in build:
760fa8a

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.

Actions #1

Updated by Alexey Khoroshilov almost 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.

Actions #2

Updated by Evgeny Novikov almost 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.

Actions #3

Updated by Evgeny Novikov almost 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.

Actions #4

Updated by Alexey Khoroshilov almost 12 years ago

And why blast worked well without aspectator? What is the difference?

Actions #5

Updated by Evgeny Novikov almost 12 years ago

Alexey Khoroshilov wrote:

And why blast worked well without aspectator? What is the difference?

BLAST works well without aspectator because of original preprocessed source code doesn't contain explicit designator's constants in initialization:
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:
  1. 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.
  2. 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).
Actions #6

Updated by Evgeny Novikov almost 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.

Actions #7

Updated by Evgeny Novikov almost 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.

Actions #8

Updated by Evgeny Novikov almost 12 years ago

  • Status changed from Open to Closed

Due to there isn't relevant problems thus far, close the issue. For pointed out bugs in BLAST and CIL issues #3562 and #3563 were opened respectively.

Actions

Also available in: Atom PDF