Skip to content

Commit c1d8eb2

Browse files
authored
Merge pull request #5931 from tautschnig/labelled-decls
C front-end: labelled declarations are only supported by Visual Studio
2 parents 6f40463 + a5f789a commit c1d8eb2

File tree

13 files changed

+177
-107
lines changed

13 files changed

+177
-107
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;

src/ansi-c/parser.y

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ extern char *yyansi_ctext;
118118

119119
/*** scanner parsed tokens (these have a value!) ***/
120120

121-
%token TOK_IDENTIFIER
121+
%token TOK_GCC_IDENTIFIER
122+
%token TOK_MSC_IDENTIFIER
122123
%token TOK_TYPEDEFNAME
123124
%token TOK_INTEGER
124125
%token TOK_FLOATING
@@ -293,7 +294,8 @@ grammar:
293294
/*** Token with values **************************************************/
294295

295296
identifier:
296-
TOK_IDENTIFIER
297+
TOK_GCC_IDENTIFIER
298+
| TOK_MSC_IDENTIFIER
297299
| TOK_CPROVER_ID TOK_STRING
298300
{
299301
// construct an identifier from a string that would otherwise not be a
@@ -1362,7 +1364,7 @@ atomic_type_specifier:
13621364
;
13631365

13641366
msc_decl_identifier:
1365-
TOK_IDENTIFIER
1367+
TOK_MSC_IDENTIFIER
13661368
{
13671369
parser_stack($$).id(parser_stack($$).get(ID_identifier));
13681370
}
@@ -2285,9 +2287,14 @@ designator:
22852287
/*** Statements *********************************************************/
22862288

22872289
statement:
2290+
declaration_statement
2291+
| statement_attribute
2292+
| stmt_not_decl_or_attr
2293+
;
2294+
2295+
stmt_not_decl_or_attr:
22882296
labeled_statement
22892297
| compound_statement
2290-
| declaration_statement
22912298
| expression_statement
22922299
| selection_statement
22932300
| iteration_statement
@@ -2297,7 +2304,6 @@ statement:
22972304
| msc_asm_statement
22982305
| msc_seh_statement
22992306
| cprover_exception_statement
2300-
| statement_attribute
23012307
;
23022308

23032309
declaration_statement:
@@ -2309,8 +2315,30 @@ declaration_statement:
23092315
}
23102316
;
23112317

2318+
gcc_attribute_specifier_opt:
2319+
/* empty */
2320+
{
2321+
init($$);
2322+
}
2323+
| gcc_attribute_specifier
2324+
;
2325+
2326+
msc_label_identifier:
2327+
TOK_MSC_IDENTIFIER
2328+
| TOK_TYPEDEFNAME
2329+
;
2330+
23122331
labeled_statement:
2313-
identifier_or_typedef_name ':' statement
2332+
TOK_GCC_IDENTIFIER ':' gcc_attribute_specifier_opt stmt_not_decl_or_attr
2333+
{
2334+
// we ignore the GCC attribute
2335+
$$=$2;
2336+
statement($$, ID_label);
2337+
irep_idt identifier=PARSER.lookup_label(parser_stack($1).get(ID_C_base_name));
2338+
parser_stack($$).set(ID_label, identifier);
2339+
mto($$, $4);
2340+
}
2341+
| msc_label_identifier ':' statement
23142342
{
23152343
$$=$2;
23162344
statement($$, ID_label);

src/ansi-c/scanner.l

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ int make_identifier()
8686
{
8787
parser_stack(yyansi_clval).id(ID_symbol);
8888
parser_stack(yyansi_clval).set(ID_C_base_name, final_base_name);
89-
return TOK_IDENTIFIER;
89+
return PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO ?
90+
TOK_MSC_IDENTIFIER : TOK_GCC_IDENTIFIER;
9091
}
9192
else
9293
{
@@ -112,7 +113,8 @@ int make_identifier()
112113
else
113114
{
114115
parser_stack(yyansi_clval).id(ID_symbol);
115-
return TOK_IDENTIFIER;
116+
return PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO ?
117+
TOK_MSC_IDENTIFIER : TOK_GCC_IDENTIFIER;
116118
}
117119
}
118120
}

0 commit comments

Comments
 (0)