Skip to content

Commit cd0e81f

Browse files
Handle function declaration appearing after definition (fix #399)
Ensure that constrains generated due to a function's declaration are applied to the variables generated at the definition even when declaration appears after the definition.
1 parent 13a0865 commit cd0e81f

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed

clang/lib/3C/ProgramInfo.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,12 @@ bool ProgramInfo::insertIntoExternalFunctionMap(ExternalFunctionMapType &Map,
450450
DiagnosticsEngine::Fatal, "duplicate definition for function %0");
451451
DE.Report(FD->getLocation(), DuplicateDefinitionsID).AddString(FuncName);
452452
exit(1);
453+
} else {
454+
// The old constraint has a body, but we've encountered another prototype
455+
// for the function.
456+
assert(OldC->hasBody() && !NewC->hasBody());
457+
NewC->brainTransplant(OldC, *this);
453458
}
454-
// else oldc->hasBody() so we can ignore the newC prototype
455459
}
456460
return RetVal;
457461
}

clang/test/3C/defn_then_decl.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: 3c -alltypes -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_ALL","CHECK" %s
2+
// RUN: 3c -addcr %s -- | FileCheck -match-full-lines -check-prefixes="CHECK_NOALL","CHECK" %s
3+
// RUN: 3c -alltypes -addcr %s -- | %clang -c -fcheckedc-extension -x c -o /dev/null -
4+
// RUN: 3c -alltypes -output-postfix=checked %s
5+
// RUN: 3c -alltypes %S/defn_then_decl.checked.c -- | count 0
6+
// RUN: rm %S/defn_then_decl.checked.c
7+
8+
// Tests for when a function's declaration appears after the same function's
9+
// definition. A particular issue that existed in caused constraints added
10+
// onto the subsequent declaration (for example, because the declaration was in
11+
// a macro) were not applied to the original definition.
12+
13+
void test0(int *p) {}
14+
#define MYDECL void test0(int *p);
15+
MYDECL
16+
17+
void test1(int *p) {}
18+
//CHECK: void test1(_Ptr<int> p) _Checked {}
19+
void test1(int *p);
20+
//CHECK: void test1(_Ptr<int> p);
21+
22+
void test2(int *p);
23+
//CHECK: void test2(_Ptr<int> p);
24+
void test2(int *p) {}
25+
//CHECK: void test2(_Ptr<int> p) _Checked {}
26+
void test2(int *p);
27+
//CHECK: void test2(_Ptr<int> p);
28+
29+
void test3(int *p) { p = 1;}
30+
//CHECK: void test3(int *p : itype(_Ptr<int>)) { p = 1;}
31+
void test3(int *p);
32+
//CHECK: void test3(int *p : itype(_Ptr<int>));
33+
34+
void test4(int *p) {}
35+
//CHECK: void test4(_Ptr<int> p) _Checked {}
36+
void test4();
37+
//CHECK: void test4(_Ptr<int> p);

0 commit comments

Comments
 (0)