Skip to content

Commit c9272d1

Browse files
committed
C front-end: labelled declarations are only supported by Visual Studio
In order to support GCC's label attributes even when the semicolon is omitted, distinguish GCC and Visual Studio modes when parsing labelled statements. See https://github.com/gcc-mirror/gcc/blob/master/gcc/c/c-parser.cc#L6070 for GCC's limitation, which we now mimic. (We already supported attributes followed by a semicolon, which GCC's documentation mandates, but the Linux kernel doesn't always follow this rule.) Fixed regression tests that had declarations immediately following a label.
1 parent 1911a2e commit c9272d1

File tree

13 files changed

+126
-55
lines changed

13 files changed

+126
-55
lines changed

regression/ansi-c/label1/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extern void foo(int *, unsigned int);
2+
3+
int main()
4+
{
5+
#ifdef _MSC_VER
6+
label:
7+
int x;
8+
#elif defined(__GNUC__)
9+
int *p;
10+
unsigned int u;
11+
label:
12+
__attribute__((unused)) foo(p, u);
13+
#endif
14+
}

regression/ansi-c/label1/test.desc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$
9+
--
10+
GCC does not permit labelling declarations as they are not considered
11+
statements, and would result in ambiguity in case of label attributes. We used
12+
to run into this problem, treating the function call in this test as a KnR
13+
function declaration.
14+
15+
Visual Studio, on the other hand, happily accepts labelled declarations.

regression/cbmc/destructors/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ int main(int argc, char **argv) {
66

77
const float *pc = (const float []){1e0, 1e1, 1e2};
88

9-
start:
9+
start:;
1010
test newAlloc0 = {0};
1111
if(argv[0])
1212
{
@@ -20,7 +20,7 @@ int main(int argc, char **argv) {
2020
if (argv[2])
2121
{
2222
test newAlloc3 = {3};
23-
nested_if:
23+
nested_if:;
2424
test newAlloc5 = {5};
2525
if (argv[3])
2626
{

regression/cbmc/symex_should_exclude_null_pointers/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ int main(int argc, char **argv) {
3838
int *ptr4 = maybe_null;
3939
goto check;
4040

41-
deref:
41+
deref:;
4242
int deref4 = *ptr4;
4343
goto end_test4;
4444

4545
check:
4646
__CPROVER_assume(ptr4 != 0);
4747
goto deref;
4848

49-
end_test4:
49+
end_test4:;
5050

5151
// Should be judged unsafe by LSPA and safe by value-set filtering
5252
// (guarded by confluence):

regression/cbmc/symex_should_filter_value_sets/main.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,28 @@ int main(int argc, char **argv)
6161
int *p7 = ptr_to_a_or_b;
6262
goto check7;
6363

64-
divide7:
64+
divide7:;
6565
int c7 = *p7;
6666
goto end_test7;
6767

6868
check7:
6969
__CPROVER_assume(p7 != &a);
7070
goto divide7;
7171

72-
end_test7:
72+
end_test7:;
7373

7474
int *p8 = ptr_to_a_or_b;
7575
goto check8;
7676

77-
divide8:
77+
divide8:;
7878
int c8 = *p8;
7979
goto end_test8;
8080

8181
check8:
8282
__CPROVER_assume(*p8 != 2);
8383
goto divide8;
8484

85-
end_test8:
85+
end_test8:;
8686

8787
// Should work (value-set filtered by confluence of if and else):
8888
int *p9 = ptr_to_a_or_b;
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
int main()
22
{
33
l2: goto l1;
4-
l1: int x=5;
5-
goto l2;
4+
l1:;
5+
int x = 5;
6+
goto l2;
67

7-
return 0;
8+
return 0;
89
}

regression/cbmc/unwind_counters3/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ int main()
22
{
33
int i=0;
44
l2: if(i==1) int y=0;
5-
l1: int x=5;
6-
goto l2;
5+
l1:;
6+
int x = 5;
7+
goto l2;
78

8-
return 0;
9+
return 0;
910
}

regression/cbmc/unwind_counters4/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ int main()
88
y = 10;
99
goto label;
1010
x = 1; // dead code, makes sure the above goto is not removed
11-
label:
11+
label:;
1212
_Bool nondet;
1313
if(nondet)
1414
__CPROVER_assert(y != 10, "violated via first loop");

regression/goto-instrument/labels1/main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ int main()
2424
x = 42;
2525
label_four:
2626
assert(foo() == 1);
27+
fptr_t fp;
2728
label_five:
28-
fptr_t fp = foo;
29+
fp = foo;
2930
assert(fp() == 1);
3031
label_six:
3132
return *p;

regression/goto-instrument/safe-dereferences/main.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ int main(int argc, char **argv) {
3030
int *ptr4 = &x;
3131
goto check;
3232

33-
deref:
33+
deref:;
3434
int deref4 = *ptr4;
3535
goto end_test4;
3636

3737
check:
3838
__CPROVER_assume(ptr4 != 0);
3939
goto deref;
4040

41-
end_test4:
41+
end_test4:;
4242

4343
// Shouldn't work yet despite being safe (guarded by confluence):
4444
int *ptr5 = &x;

0 commit comments

Comments
 (0)