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
Lines changed: 15 additions & 0 deletions
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+
}
Lines changed: 9 additions & 0 deletions
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

Lines changed: 10 additions & 10 deletions
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

Lines changed: 2 additions & 3 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 12 additions & 0 deletions
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

0 commit comments

Comments
 (0)