Skip to content

Commit c266ea3

Browse files
authored
Merge pull request #8160 from tautschnig/bugfixes/no-duplicate-decl
C front-end: refuse duplicate declaration of local variable
2 parents 79fafbe + e466dbe commit c266ea3

File tree

11 files changed

+90
-43
lines changed

11 files changed

+90
-43
lines changed
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// duplicate globals are accepted by compilers
2+
int x;
3+
int x;
4+
5+
int main()
6+
{
7+
int a = 10;
8+
9+
// gcc: error: redeclaration of 'a' with no linkage
10+
int a;
11+
12+
a++;
13+
14+
return 0;
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
4+
redeclaration of 'main::1::a' with no linkage$
5+
CONVERSION ERROR
6+
^EXIT=(1|64)$
7+
^SIGNAL=0$
8+
--
9+
redeclaration of 'x' with no linkage$

regression/cbmc-shadow-memory/nondet-size-arrays1/main.c

+10-10
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ int main()
6969
assert(__CPROVER_get_field(z + 4, "field1") == 15);
7070
assert(__CPROVER_get_field(z + 4, "field2") == 16);
7171

72-
int i;
73-
__CPROVER_assume(0 <= i && i < n);
74-
__CPROVER_set_field(&(B[i]), "field1", 42);
75-
assert(__CPROVER_get_field(&(B[i]), "field1") == 42);
72+
int j;
73+
__CPROVER_assume(0 <= j && j < n);
74+
__CPROVER_set_field(&(B[j]), "field1", 42);
75+
assert(__CPROVER_get_field(&(B[j]), "field1") == 42);
7676

77-
z = &(B[i]);
77+
z = &(B[j]);
7878
__CPROVER_set_field(z, "field1", 43);
7979
assert(__CPROVER_get_field(z, "field1") == 43);
8080

@@ -101,12 +101,12 @@ int main()
101101
assert(__CPROVER_get_field(z + 4, "field1") == 15);
102102
assert(__CPROVER_get_field(z + 4, "field2") == 16);
103103

104-
int i;
105-
__CPROVER_assume(0 <= i && i < n);
106-
__CPROVER_set_field(&(C[i]), "field1", 42);
107-
assert(__CPROVER_get_field(&(C[i]), "field1") == 42);
104+
int l;
105+
__CPROVER_assume(0 <= l && l < n);
106+
__CPROVER_set_field(&(C[l]), "field1", 42);
107+
assert(__CPROVER_get_field(&(C[l]), "field1") == 42);
108108

109-
z = &(C[i]);
109+
z = &(C[l]);
110110
__CPROVER_set_field(z, "field1", 43);
111111
assert(__CPROVER_get_field(z, "field1") == 43);
112112
}

regression/goto-analyzer-simplify/simplify-lhs-member/main.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ void main()
1111
struct test_struct value;
1212

1313
// Simplify a pointer inside a struct
14-
int symbol;
1514
value.pointer_component = &symbol;
1615

1716
// Simplify
@@ -37,6 +36,6 @@ void main()
3736
value.array[constant] = 2;
3837

3938
// No simplification
40-
int nondet;
41-
value.array[nondet] = 3;
39+
int nondet2;
40+
value.array[nondet2] = 3;
4241
}

regression/goto-analyzer/pointer-comparison-equality-struct-members/main.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int main()
2222
assert(pa == &(y.a));
2323
assert(pa != &(y.a));
2424

25-
int *pb = &(x.b);
26-
assert(pb == &(y.a));
27-
assert(pb != &(y.a));
25+
int *pc = &(x.b);
26+
assert(pc == &(y.a));
27+
assert(pc != &(y.a));
2828
}

regression/goto-analyzer/pointer-comparison-equality-struct-members/test-constants.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ main.c
99
^\[main.assertion.4\] .* assertion pb != &\(x.a\): SUCCESS
1010
^\[main.assertion.5\] .* assertion pa == &\(y.a\): FAILURE
1111
^\[main.assertion.6\] .* assertion pa != &\(y.a\): SUCCESS
12-
^\[main.assertion.7\] .* assertion pb == &\(y.a\): FAILURE
13-
^\[main.assertion.8\] .* assertion pb != &\(y.a\): SUCCESS
12+
^\[main.assertion.7\] .* assertion pc == &\(y.a\): FAILURE
13+
^\[main.assertion.8\] .* assertion pc != &\(y.a\): SUCCESS

regression/goto-analyzer/pointer-comparison-equality-struct-members/test-top-bottom.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ main.c
99
^\[main.assertion.4\] .* assertion pb != &\(x.a\): UNKNOWN
1010
^\[main.assertion.5\] .* assertion pa == &\(y.a\): UNKNOWN
1111
^\[main.assertion.6\] .* assertion pa != &\(y.a\): UNKNOWN
12-
^\[main.assertion.7\] .* assertion pb == &\(y.a\): UNKNOWN
13-
^\[main.assertion.8\] .* assertion pb != &\(y.a\): UNKNOWN
12+
^\[main.assertion.7\] .* assertion pc == &\(y.a\): UNKNOWN
13+
^\[main.assertion.8\] .* assertion pc != &\(y.a\): UNKNOWN

regression/goto-analyzer/pointer-comparison-equality-struct-members/test-value-set.desc

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ main.c
99
^\[main.assertion.4\] .* assertion pb != &\(x.a\): SUCCESS
1010
^\[main.assertion.5\] .* assertion pa == &\(y.a\): FAILURE
1111
^\[main.assertion.6\] .* assertion pa != &\(y.a\): SUCCESS
12-
^\[main.assertion.7\] .* assertion pb == &\(y.a\): FAILURE
13-
^\[main.assertion.8\] .* assertion pb != &\(y.a\): SUCCESS
12+
^\[main.assertion.7\] .* assertion pc == &\(y.a\): FAILURE
13+
^\[main.assertion.8\] .* assertion pc != &\(y.a\): SUCCESS

regression/goto-analyzer/sensitivity-test-common-files/array_of_pointer_sensitivity_tests.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -157,16 +157,16 @@ int main()
157157
int x = 4;
158158
int y = 5;
159159
int *ps[2] = {&x, &y};
160-
int i;
160+
int l;
161161
if(nondet > 2)
162162
{
163-
i = 0;
163+
l = 0;
164164
}
165165
else
166166
{
167-
i = 1;
167+
l = 1;
168168
}
169-
*(ps[i]) = 4;
169+
*(ps[l]) = 4;
170170

171171
__CPROVER_assert(*ps[0] == 4, "*ps[0]==4");
172172
__CPROVER_assert(*ps[1] == 4, "*ps[1]==4");

src/ansi-c/c_typecheck_base.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,19 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
141141
if(symbol.is_type)
142142
typecheck_redefinition_type(existing_symbol, symbol);
143143
else
144+
{
145+
if(
146+
(!old_it->second.is_static_lifetime || !symbol.is_static_lifetime) &&
147+
symbol.type.id() != ID_code)
148+
{
149+
error().source_location = symbol.location;
150+
error() << "redeclaration of '" << symbol.display_name()
151+
<< "' with no linkage" << eom;
152+
throw 0;
153+
}
154+
144155
typecheck_redefinition_non_type(existing_symbol, symbol);
156+
}
145157
}
146158
}
147159

unit/compound_block_locations.cpp

+29-17
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,11 @@ SCENARIO("Compound blocks should have a location")
107107
"/* 4 */ { \n"
108108
"/* 5 */ int x; \n"
109109
"/* 6 */ if(x) \n"
110-
"/* 7 */ int x = 1; \n"
111-
"/* 8 */ } \n"
112-
"/* 9 */ } \n",
110+
"/* 7 */ { \n"
111+
"/* 8 */ int x = 1; \n"
112+
"/* 9 */ } \n"
113+
"/* 10 */ } \n"
114+
"/* 11 */ } \n",
113115
{{ID_while, 3}, {ID_ifthenelse, 6}});
114116

115117
checker.check(
@@ -233,21 +235,31 @@ SCENARIO("Compound blocks should have a location")
233235
"/* 4 */ switch(x) \n"
234236
"/* 5 */ { \n"
235237
"/* 6 */ case 1: \n"
236-
"/* 7 */ int y = 1; \n"
237-
"/* 8 */ break; \n"
238-
"/* 9 */ case 2: \n"
239-
"/* 10 */ int y = 2; \n"
240-
"/* 11 */ int z = 2; \n"
241-
"/* 12 */ break; \n"
242-
"/* 13 */ case 3: \n"
243-
"/* 14 */ int y = 3; \n"
244-
"/* 15 */ case 4: \n"
245-
"/* 16 */ int y = 4; \n"
246-
"/* 17 */ break; \n"
247-
"/* 18 */ default: \n"
248-
"/* 19 */ int y = 5; \n"
238+
"/* 7 */ { \n"
239+
"/* 8 */ int y = 1; \n"
240+
"/* 9 */ break; \n"
241+
"/* 10 */ } \n"
242+
"/* 11 */ case 2: \n"
243+
"/* 12 */ { \n"
244+
"/* 13 */ int y = 2; \n"
245+
"/* 14 */ int z = 2; \n"
246+
"/* 15 */ break; \n"
247+
"/* 16 */ } \n"
248+
"/* 17 */ case 3: \n"
249+
"/* 18 */ { \n"
250+
"/* 19 */ int y = 3; \n"
249251
"/* 20 */ } \n"
250-
"/* 21 */ } \n",
252+
"/* 21 */ case 4: \n"
253+
"/* 22 */ { \n"
254+
"/* 23 */ int y = 4; \n"
255+
"/* 24 */ break; \n"
256+
"/* 25 */ } \n"
257+
"/* 26 */ default: \n"
258+
"/* 27 */ { \n"
259+
"/* 28 */ int y = 5; \n"
260+
"/* 29 */ } \n"
261+
"/* 30 */ } \n"
262+
"/* 31 */ } \n",
251263
{{ID_switch, 6}});
252264
}
253265

0 commit comments

Comments
 (0)