Closed john-h-kastner closed 4 years ago
A related and slightly more worrying brother of this issue, where a user defined unchecked cast causes the converted program not to compile.
Original | Converted |
---|---|
void foo() {
int *a = (int*) 0;
int **b = (int**) 0;
}
|
void foo() {
_Ptr
|
The converted code fails to compile with the following error message:
error: initializing '_Ptr<_Ptr<int>>' with an expression of incompatible type 'int **'
_Ptr<_Ptr<int>> b = (int**) 0;
Some notes: complex_expression.c
and ptrint.c
tests both fail because of this. Note that Shilpa's followup actually fails to compile; this is a bug, not a nicety. Can extend the map from source locations to constraint variables, and then set a constraint variable with a cast, so it can be rewritten (e.g., either dropped, or changed to a Checked C cast).
I found an instance of this issue that actually results in output that won't compile.
void c(int ***e) {}
void d() {
int *b = 1;
int **a = &b;
c(&a);
}
converts to this
void c(_Ptr<_Ptr<int *>> e) {}
void d() {
int *b = 1;
_Ptr<int *> a = &b;
c(((int ***)&a));
}
which clang rejects
test.checked.c:6:5: error: passing 'int ***' to parameter of incompatible type '_Ptr<_Ptr<int *>>'
c(((int ***)&a));
Removing the (int ***)
cast fixes it.
Fixed by #257
Function arguments are cast to
int**
when the corresponding parameter is_Ptr<int*>
. In the following example, the cast can be removed, and it will still compile.I don't think this has the same underlying issue as #134. The place to start looking is probably this line in
GatherTool.cpp
.https://github.com/plum-umd/checkedc-clang/blob/85c92041bd1e058b6781fd9deaa8a0f629e58b8d/clang/lib/CConv/GatherTool.cpp#L36
It considers a parameter
WILD
if any of its atoms are wild, so a checked pointer to an unchecked pointer isWILD
even though the outermost pointer is checked.